字典樹的變形,常規字典樹用來求前綴的,所以把每個單詞拆成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\n",j); } return 0; }