hihocoder 1014
题意是去后缀是输入字符串s的的个数。
首先用结构体做,结构体更实现,而且通俗易懂些。一直建立数,每次建立都往子节点加1,查找的时候找到最后那个字母时,输出它的子节点的数字就可以了。
1 #include <iostream> 2 #include <stdio.h> 3 #include <malloc.h> 4 using namespace std; 5 struct Nod{ 6 int num; 7 Nod* next[26]; 8 Nod(){ 9 int num = 0; 10 for(int i = 0; i < 26; i ++) 11 next[i] = NULL; 12 } 13 }t; 14 int n,m; 15 char s[11], ss[11]; 16 void mkTrie(char* c){ 17 Nod* p = &t; 18 for(int i = 0; c[i]; i ++){ 19 int a = c[i]-'a'; 20 if(p->next[a] == NULL){ 21 struct Nod* b = (struct Nod*)malloc(sizeof(struct Nod)); 22 p->next[a] = b; 23 //p->next[a] = new Nod; 24 } 25 p = p->next[a]; 26 p->num++; 27 } 28 } 29 int find(char *c){ 30 Nod* p = &t; 31 for(int i = 0; c[i]; i ++){ 32 int a = c[i]-'a'; 33 if(p->next[a] == NULL) return 0; 34 p = p->next[a]; 35 } 36 return p->num; 37 } 38 int main(){ 39 scanf("%d",&n); 40 for(int i = 0; i < n; i ++) scanf("%s",s),mkTrie(s); 41 scanf("%d",&m); 42 while(m--){ 43 scanf("%s",ss); 44 printf("%d ",find(ss)); 45 } 46 return 0; 47 }
也可以用数组实现,不过更麻烦些。
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 int sum[100000*26][26], sz = 1,n, m, trie[100000*26]; 5 char s[11]; 6 7 void mkTrie(){ 8 int root = 0; 9 for(int i = 0; s[i]; i ++){ 10 int a = s[i]-'a'; 11 if(!sum[root][a]) sum[root][a] = sz++; 12 trie[root]++; 13 root = sum[root][a]; 14 } 15 trie[root]++; 16 } 17 int find(){ 18 int root = 0; 19 for(int i = 0; s[i]; i ++){ 20 int a = s[i] - 'a'; 21 if(sum[root][a])root=sum[root][a]; 22 else return 0; 23 } 24 return trie[root]; 25 } 26 int main(){ 27 scanf("%d",&n); 28 for(int i = 0; i < n; i ++){ 29 scanf("%s",s); 30 mkTrie(); 31 } 32 scanf("%d",&m); 33 while(m--){ 34 scanf("%s",s); 35 printf("%d ",find()); 36 } 37 return 0; 38 }