题意:
一串数字,给出出现频率最高的那个单词。
思路:
字典树:首先是建树,其实最麻烦的是概率处理部分,因为题目给定的单词都是按照字典有序排列的,所以可以对于概率进行一遍预处理,然后建树的时候就可以直接更新判断了。
题目同 POJ 1451 http://poj.org/problem?id=1451
#include <iostream> #include <vector> using namespace std; struct node { bool isword; int prob, index; int child[10];
node(bool _isword, int _prob, int _index) : isword(_isword), prob(_prob), index(_index) { memset(child, 0, sizeof(child)); } };
vector<node> trie; int tab[256]; char dict[1010][102]; int prob[1010][102]; void Insert(const char* word, int i, int index, int rt) { if (word[i] == '\0') {
trie[rt].isword = true; return ; } int m = tab[word[i]]; if (trie[rt].child[m]) { if (trie[trie[rt].child[m]].prob < prob[index][i]) {
trie[trie[rt].child[m]].prob = prob[index][i];
trie[trie[rt].child[m]].index = index; } else if (trie[trie[rt].child[m]].prob == prob[index][i]) { if (strncmp(dict[index], dict[trie[trie[rt].child[m]].index], i + 1) < 0)
trie[trie[rt].child[m]].index = index; }
Insert(word, i + 1, index, trie[rt].child[m]); } else {
trie.push_back(node(false, 0, 0));
trie[rt].child[m] = trie.size() - 1;
trie[trie[rt].child[m]].index = index;
trie[trie[rt].child[m]].prob = prob[index][i];
Insert(word, i + 1, index, trie[rt].child[m]); } } int Query(const char* word, int rt) { if (*word == '\0') return trie[rt].index; int m = *word - '0'; if (!trie[rt].child[m]) return -1; else return Query(word + 1, trie[rt].child[m]); } void Init() {
tab['a'] = tab['b'] = tab['c'] = 2;
tab['d'] = tab['e'] = tab['f'] = 3;
tab['g'] = tab['h'] = tab['i'] = 4;
tab['j'] = tab['k'] = tab['l'] = 5;
tab['m'] = tab['n'] = tab['o'] = 6;
tab['p'] = tab['q'] = tab['r'] = tab['s'] = 7;
tab['t'] = tab['u'] = tab['v'] = 8;
tab['w'] = tab['x'] = tab['y'] = tab['z'] = 9; } int main() { int cases;
Init();
scanf("%d", &cases); for (int c = 1; c <= cases; ++c) { int n, p;
scanf("%d", &n);
printf("Scenario #%d:\n", c);
trie.clear();
trie.push_back(node(false, 0, 0));
memset(prob, 0, sizeof(prob)); for (int i = 1; i <= n; ++i) {
scanf("%s %d", dict[i], &p); int len = strlen(dict[i-1]); for (int j = 0; dict[i][j] != '\0'; ++j) {
prob[i][j] = p; if (j < len && !strncmp(dict[i], dict[i-1], j + 1))
prob[i][j] += prob[i-1][j]; }
Insert(dict[i], 0, i, 0); } char word[110], is[110], os[110];
scanf("%d", &n); while (n--) {
scanf("%s", is); for (int i = 0; is[i] != '1'; ++i) {
word[i] = is[i];
word[i+1] = '\0'; int id = Query(word, 0); if (id != -1) { int j = 0; for (j = 0; j <= i; ++j)
os[j] = dict[id][j];
os[j] = '\0';
printf("%s\n", os); } else
printf("MANUALLY\n"); }
printf("\n"); }
printf("\n"); } return 0; }