poj 2001 Shortest Prefixes ——字典树入门


题目链接: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 }

先建树,再查找,一边查找一遍输出即可。

原文地址:https://www.cnblogs.com/liuxueyang/p/2934430.html