字典树的变形,常规字典树用来求前缀的,所以把每个单词拆成len个词建树,为了避免abab这样的查ab时会出现两次,每次加一个标记,如果该节点上次的建树的单词与本次相同就不更新,否则更新
#include<stdio.h> #include<string.h> #include<stdlib.h> struct tree { struct tree *son[26]; int count; int flag; }*root; void insert(char *p,int id) { int i,k,j; tree *cur=root,*next; int len=strlen(p); for(i=0;i<len;i++) { k=p[i]-'a'; if(cur->son[k]!=NULL) cur=cur->son[p[i]-'a']; else { next=new(tree); for(j=0;j<26;j++) next->son[j]=NULL; next->count=0; next->flag=-1; cur->son[p[i]-'a']=next; cur=next; } if(cur->flag!=id)//如果上次在该节点更新的单词与本次单词不同就更新 { cur->count++; cur->flag=id; } } } int find(char *p) { int i; tree *cur=root; int len=strlen(p); for(i=0;i<len;i++) { int k=p[i]-'a'; if(cur->son[k]==NULL) break; else cur=cur->son[k]; } if(i<len) return 0; return cur->count; } int main() { int i,j,n,m; char s[25]; root=new(tree); for(i=0;i<26;i++) root->son[i]=NULL; root->count=0; root->flag=-1; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%s",s); for(j=0;s[j];j++) { insert(s+j,i);//拆单词建树 } } scanf("%d",&m); while(m--) { scanf("%s",s); j=find(s); printf("%d ",j); } return 0; }