题目链接:http://poj.org/problem?id=2001
题目大意:
给一系列单词,找出么每个单词的最小缩写,使得这些缩写不出现歧义。还有,完全相同的优先级比前缀的优先级高,意思就是,如果一个单词的缩写就是这个单词本身,那么它不能代表以它为前缀的单词,而仅仅代表它本身。
题目思路:
第一道字典树题目,写代码还是要认真,出一些写错误是最吃亏的。减少错误的办法就是,第一,多敲代码,敲熟练一点儿,孰能生巧。第二,写代码的过程中要养成习惯,就是先把问题想透彻,再写,一边写一边思考。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 6 using namespace std; 7 8 char a[1000+10][25]; 9 const int sonnum = 26, base = 'a'; 10 11 struct Trie 12 { 13 int num; 14 bool terminal; 15 struct Trie *son[sonnum]; 16 }; 17 18 Trie *NewTrie() 19 { 20 Trie *temp = new Trie; 21 temp->num = 1; temp->terminal = false; 22 for (int i = 0; i < sonnum; ++i) temp->son[i] = NULL; 23 return temp; 24 } 25 26 void Insert(Trie *pnt, char *s, int len) 27 { 28 Trie *temp = pnt; 29 for (int i = 0; i < len; ++i) 30 { 31 if (temp->son[s[i]-base] == NULL) 32 temp->son[s[i]-base] = NewTrie(); 33 else temp->son[s[i]-base]->num++; 34 temp = temp->son[s[i]-base]; 35 } 36 temp->terminal = true; 37 } 38 Trie *Find(Trie *pnt, char *s, int len) 39 { 40 Trie *temp = pnt; 41 for (int i = 0; i < len; ++i) 42 { 43 if (temp->son[s[i]-base]->num == 1) 44 { 45 printf("%c", s[i]); 46 return temp; 47 } 48 printf("%c", s[i]); 49 temp = temp->son[s[i]-base]; 50 } 51 return temp; 52 } 53 54 int main(void) 55 { 56 #ifndef ONLINE_JUDGE 57 freopen("poj2001.in", "r", stdin); 58 #endif 59 int cnt = 0; 60 Trie *tree = NewTrie(); 61 while (~scanf("%s", a[cnt])) 62 { 63 Insert(tree, a[cnt], strlen(a[cnt])); 64 cnt++; 65 } 66 for (int i = 0; i < cnt; ++i) 67 { 68 printf("%s ", a[i]); 69 Find(tree, a[i], strlen(a[i])); 70 printf("\n"); 71 } 72 73 return 0; 74 }
先建树,再查找,一边查找一遍输出即可。