*HDU1251 字典树
统计难题
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 35639 Accepted Submission(s): 13322
Problem Description
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每个提问都是一个字符串.
注意:本题只有一组测试数据,处理到文件结束.
注意:本题只有一组测试数据,处理到文件结束.
Output
对于每个提问,给出以该字符串为前缀的单词的数量.
Sample Input
banana
band
bee
absolute
acm
ba
b
band
abc
Sample Output
2
3
1
0
Author
Ignatius.L
代码:
1 //动态字典树模板 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<malloc.h> 6 using namespace std; 7 struct Trie 8 { 9 int v; 10 Trie *next[26]; //26个小写英文字母,v在这里保存到每个节点有几个单词,根据题意变化 11 }; 12 Trie *root; 13 void Tinsert(char s[]) 14 { 15 int len=strlen(s); 16 Trie *p=root,*q; 17 for(int i=0;i<len;i++) 18 { 19 int id=s[i]-'a'; //换成编号 20 if(p->next[id]==NULL) 21 { 22 q=new Trie; 23 for(int j=0;j<=26;j++) 24 q->next[j]=NULL; 25 q->v=0; 26 p->next[id]=q; 27 } 28 p=p->next[id]; 29 p->v++; 30 } 31 } 32 int Tsearch(char s[]) 33 { 34 int len=strlen(s); 35 Trie *p=root; 36 for(int i=0;i<len;i++) 37 { 38 int id=s[i]-'a'; 39 if(p->next[id]==NULL) 40 return 0; 41 p=p->next[id]; 42 } 43 return p->v; 44 } 45 void Tdelete(Trie *t) //动态字典树释放内存 46 { 47 if(t==NULL) 48 return; 49 for(int i=0;i<26;i++) 50 if(t->next[i]!=NULL) 51 Tdelete(t->next[i]); 52 free(t); 53 } 54 int main() 55 { 56 char ch[20]; 57 root=new Trie; 58 for(int i=0;i<26;i++) 59 root->next[i]=NULL; 60 root->v=0; 61 while(gets(ch)&&ch[0]) 62 Tinsert(ch); 63 while(scanf("%s",ch)!=EOF) 64 printf("%d\n",Tsearch(ch)); 65 Tdelete(root); 66 return 0; 67 }
1 //仿照上面的动态字典树写的一个静态字典树 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 int const MAX=1000000; //树节点总数 7 int const CON=26; //26个小写英文字母 8 int nod[MAX][CON],val[MAX]; //节点,节点权值 9 int sz; //记录节点序号 10 void init() 11 { 12 sz=1; 13 memset(nod[0],0,sizeof(nod[0])); 14 val[0]=0; 15 } 16 void insert(char s[]) 17 { 18 int len=strlen(s); 19 int rt=0; 20 for(int i=0;i<len;i++) 21 { 22 int id=s[i]-'a'; 23 if(nod[rt][id]==0) 24 { 25 memset(nod[sz],0,sizeof(nod[sz])); 26 nod[rt][id]=sz; 27 val[sz++]=0; 28 } 29 rt=nod[rt][id]; 30 val[rt]++; 31 } 32 } 33 int search(char s[]) 34 { 35 int len=strlen(s); 36 int rt=0; 37 for(int i=0;i<len;i++) 38 { 39 int id=s[i]-'a'; 40 if(nod[rt][id]==0) 41 return 0; 42 rt=nod[rt][id]; 43 } 44 return val[rt]; 45 } 46 int main() 47 { 48 char ch[20]; 49 init(); 50 while(gets(ch)&&ch[0]) 51 insert(ch); 52 while(scanf("%s",ch)!=EOF) 53 printf("%d\n",search(ch)); 54 return 0; 55 }