题意:T9输入法,要求根据给出的字典,对给定的数字顺序,选择具有最高频率的词前缀。
解法:经典的字典树问题。根据字典词,建立字典树(Trie树),节点保存其权值(频率),对给定的数字进行搜索(DFS),确定最大值。
具有相同最大值是,输出字典序靠前前缀。

源代码
1
#include<iostream>
2
#include<stack>
3
//#include<fstream>
4
5
using namespace std;
6
7
//字典树节点
8
struct Node
9

{
10
int p; //频率
11
int lev; //节点处在的层,搜索时需用
12
char c; //节点对应的字符,此题搜索时要用,一般字典序可能不必
13
Node *letter[26];
14
};
15
16
Node *root;
17
18
//向字典树中加入一单词
19
void InsertWord(const char *word, const int &pro)
20

{
21
Node *ptr = root;
22
int len = strlen(word);
23
24
for(int i=0; i<len; i++)
25
{
26
int index = word[i] - 'a';
27
if(ptr->letter[index] == NULL)
28
{
29
ptr->letter[index] = new Node();
30
ptr->letter[index]->p = pro;
31
ptr->letter[index]->c = word[i];
32
}
33
else
34
{
35
ptr->letter[index]->p += pro;
36
}
37
ptr = ptr->letter[index];
38
}
39
}
40
41
//清除字典树
42
void DelTree(Node *p)
43

{
44
for(int i=0; i<26; i++)
45
{
46
if(p->letter[i] != NULL)
47
{
48
DelTree(p->letter[i]);
49
}
50
}
51
delete p;
52
}
53
54
//从字典树中找出数字串对应的最大频率单词前缀
55
char* FindWord(const char *dec,int e)
56

{
57
int mTable[10][4] =
{
{/**//*0,0,0,0*/},
{/**//*0,0,0,0*/},
{0,1,2,0},
{3,4,5,0},
{6,7,8,0}, //按键数字对应的字符映射表
58
{9,10,11,0},
{12,13,14,0},
{15,16,17,18},
{19,20,21,0},
{22,23,24,25}};
59
60
Node *ptr = root;
61
int maxP = 0;
62
char word[101]; //当前获得的前缀串
63
char *ans = new char[101]; //频率最大前缀串
64
65
stack<Node*> sq;
66
67
Node *cur,*nex;
68
69
cur = root;
70
cur->lev = -1;
71
sq.push(cur);
72
73
while(!sq.empty())
74
{
75
cur = sq.top();
76
sq.pop();
77
78
if(cur->lev > -1)
79
{
80
word[cur->lev] = cur->c;
81
}
82
83
if(cur->lev == e) //当层数与数字串位数相等时即判断
84
{
85
if(maxP <= cur->p) //注意相等情况,用于处理权值相等时的前缀选择(字典序靠前)
86
{
87
maxP = cur->p;
88
for(int i=0; i<=e; i++)
89
{
90
ans[i] = word[i];
91
}
92
}
93
}
94
else
95
{
96
int n = (dec[cur->lev + 1] == '7' || dec[cur->lev + 1] == '9') ? 4 : 3;
97
for(int i=0; i<n; i++)
98
{
99
int index = mTable[dec[cur->lev + 1] - '0'][i];
100
nex = cur->letter[index];
101
if(nex != NULL)
102
{
103
nex->lev = cur->lev + 1;
104
sq.push(nex);
105
}
106
}
107
}
108
}
109
if(maxP == 0)
110
{
111
return "MANUALLY";
112
}
113
114
ans[e + 1] = '\0';
115
return ans;
116
}
117
118
int main()
119

{
120
int nCase;
121
int w,m;
122
char word[101];
123
int p;
124
125
char dec[101];
126
127
/**//*ifstream infile("input.txt");
128
ofstream outfile("output.txt");*/
129
130
cin>>nCase;
131
//infile>>nCase;
132
for(int k=1; k<=nCase; k++)
133
{
134
root = new Node();
135
136
cin>>w;
137
//infile>>w;
138
for(int i=0; i<w; i++)
139
{
140
cin>>word>>p;
141
//infile>>word>>p;
142
InsertWord(word,p);
143
}
144
cin>>m;
145
//infile>>m;
146
147
cout<<"Scenario #"<<k<<":"<<endl;
148
//outfile<<"Scenario #"<<k<<":"<<endl;
149
for(int i=0; i<m; i++)
150
{
151
cin>>dec;
152
//infile>>dec;
153
154
int len = strlen(dec) - 1;
155
for(int j=0; j<len; j++)
156
{
157
cout<<FindWord(dec,j)<<endl;
158
//outfile<<FindWord(dec,j)<<endl;
159
}
160
cout<<endl;
161
//outfile<<endl;
162
}
163
cout<<endl;
164
DelTree(root); //每次必须清空字典树,以防止影响后面新字典树的建立
165
}
166
/**//*infile.close();
167
outfile.close();*/
168
system("Pause");
169
return 0;
170
}