HDU-1251 统计难题 (Trie)

题目:

Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).

Input

输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.

注意:本题只有一组测试数据,处理到文件结束.

Output

对于每个提问,给出以该字符串为前缀的单词的数量.

Sample Input

banana
band
bee
absolute
acm

ba
b
band
abc

Sample Output

2
3
1
0


思路:

  • Trie字典树模板题,我用了两种做法,一种是指针写的,一种是汪神传授的数组模拟,数组一开始过不去问学长说数组要开大一点。
  • 数组模拟Trie有一点我想了很久才明白,就是ch[1][x]只记录每个串第一个位置的下标,相当于一个入口,如果要标记或者计数是不考虑它的。
  • 这题提交要用C++,G++会MLE。

链式Trie代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<set>
 8 
 9 using namespace std;
10 
11 typedef struct TrieNode{
12     int cnt;
13     bool flag;
14     TrieNode *next[26];
15     TrieNode(){
16         cnt = 0;
17         flag = false;
18         memset(next, 0, sizeof(next));
19     }
20 }TrieNode, *Trie;
21 
22 TrieNode *InitTrieNode(){
23     TrieNode *p = new TrieNode;
24     return p;
25 }
26 
27 void InsertNode(Trie root, char *word){
28     Trie p = root;
29     char *ch = word;
30     int id;
31     while(*ch){
32         id = *ch - 'a';
33         if (p->next[id] == NULL)
34             p->next[id] = InitTrieNode();
35         p = p->next[id];
36         p->cnt++;
37         ++ch;
38     }
39     p->flag = true;
40 }
41 
42 int TrieSearch(Trie root, char *word){
43     Trie p = root;
44     char *ch = word;
45     int id;
46     bool ans = false;
47     while(*ch){
48         id = *ch - 'a';
49         if (p->next[id] == NULL)
50             return 0;
51         p = p->next[id];
52         ++ch;
53     }
54     return p->cnt;
55 }
56 
57 int main()
58 {
59     Trie root = InitTrieNode();
60     char ch[15], c;
61     while(gets(ch), ch[0]){
62         InsertNode(root, ch);
63     }
64     while(scanf("%s", &ch) != EOF){
65         printf("%d\n", TrieSearch(root, ch));
66     }
67 
68     return 0;
69 }

 

数组模拟Trie代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<set>
 8 
 9 using namespace std;
10 int ch[1100000][26], cnt[1100000], fir[26], num = 1;
11 
12 void Insert(char *word){
13     int now = 1, len = strlen(word), id;
14     for (int i = 0; i < len; ++i){
15         id = word[i] - 'a';
16         if (ch[now][id]) now = ch[now][id];
17         else now = ch[now][id] = ++num;
18         ++cnt[now];
19     }
20 }
21 
22 int Search(char *pre){
23     int len = strlen(pre), now = 1, id;
24     for (int i = 0; i < len; ++i){
25         id = pre[i] - 'a';
26         if (ch[now][id]) now = ch[now][id];
27         else return 0;
28     }
29     return cnt[now];
30 }
31 
32 int main()
33 {
34     char word[20], c;
35     while(gets(word), word[0]){
36         Insert(word);
37     }
38     while(scanf("%s", &word) != EOF){
39         printf("%d\n", Search(word));
40     }
41 
42     return 0;
43 }

 

posted @ 2017-01-13 11:53  Robin!  阅读(134)  评论(0编辑  收藏  举报