AC自助机
http://blog.henix.info/blog/trie-aho-corasick.html
这个博客说的很清楚了。自己实现了个,留个模版
View Code
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 using namespace std; 5 6 struct node 7 { 8 struct node *fail; 9 struct node *next[26]; 10 int cnt; 11 node() 12 { 13 cnt=0; 14 fail=NULL; 15 for(int i=0;i<26;i++) 16 next[i]=NULL; 17 } 18 }; 19 node *root; 20 char str[1000001]; 21 int n; 22 23 void insert(char word[]) 24 { 25 int i=0,len=strlen(word); 26 node *tmp=root; 27 if(tmp==NULL) 28 { 29 tmp=new node(); 30 root=tmp; 31 } 32 while(word[i]) 33 { 34 int b=word[i]-'a'; 35 if(tmp->next[b]==NULL) 36 { 37 tmp->next[b]=new node(); 38 } 39 if(i==len-1) 40 tmp->next[b]->cnt++; 41 tmp=tmp->next[b]; 42 i++; 43 } 44 } 45 46 node *q[500010]; 47 int head,tail; 48 49 void addFail() 50 { 51 head=tail=0; 52 q[tail++]=root; 53 while(head<tail) 54 { 55 node *x=q[head++]; 56 int i; 57 for(i=0;i<26;i++) 58 { 59 if(x->next[i]!=NULL) 60 { 61 q[tail++]=x->next[i]; 62 node *t=x->fail; 63 while((t!=NULL) && t->next[i]==NULL) 64 t=t->fail; 65 if(t==NULL) 66 x->next[i]->fail=root; 67 else 68 x->next[i]->fail=t->next[i]; 69 } 70 } 71 } 72 } 73 74 int match(char word[]) 75 { 76 int i=0,ans=0; 77 node *tmp=root; 78 while(word[i]) 79 { 80 int b=word[i]-'a'; 81 while(tmp!=NULL && tmp->next[b]==NULL) 82 tmp=tmp->fail; 83 if(tmp!=NULL) 84 { 85 tmp=tmp->next[b]; 86 node *t=tmp; 87 while(t!=NULL) 88 { 89 if(t->cnt>0) 90 { 91 ans+=t->cnt; 92 t->cnt=0; 93 } 94 t=t->fail; 95 } 96 } 97 else 98 tmp=root; 99 i++; 100 } 101 return ans; 102 } 103 104 int main() 105 { 106 int i,cas; 107 freopen("D:\\in.txt","r",stdin); 108 scanf("%d",&cas); 109 while(cas--) 110 { 111 scanf("%d",&n); 112 root=NULL; 113 for(i=0;i<n;i++) 114 { 115 scanf("%*c%s",str); 116 insert(str); 117 } 118 scanf("%*c%s",str); 119 addFail(); 120 int ans=match(str); 121 printf("%d\n",ans); 122 } 123 return 0; 124 }
View Code
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 using namespace std; 5 6 struct node 7 { 8 int cnt; 9 struct node *fail; 10 struct node *next[26]; 11 }; 12 13 node root[500010]; 14 int n,num; 15 char str[1000001]; 16 17 void insert(char word[]) 18 { 19 int i=0; 20 node * tmp=root; 21 while(word[i]) 22 { 23 int b=word[i]-'a'; 24 if(tmp->next[b]==NULL) 25 { 26 tmp->next[b]=root+num; 27 memset(root+num,0,sizeof(struct node)); 28 num++; 29 } 30 tmp=tmp->next[b]; 31 i++; 32 } 33 tmp->cnt++; 34 } 35 36 node *q[500010]; 37 int head,tail; 38 39 void add_Fail() 40 { 41 head=tail=0; 42 q[tail++]=root; 43 while(head<tail) 44 { 45 node *x=q[head++]; 46 for(int i=0;i<26;i++) 47 { 48 if(x->next[i]!=NULL) 49 { 50 q[tail++]=x->next[i]; 51 node *t=x->fail; 52 while((t!=NULL) && t->next[i]==NULL) 53 t=t->fail; 54 if(t==NULL) 55 x->next[i]->fail=root; 56 else 57 x->next[i]->fail=t->next[i]; 58 } 59 } 60 } 61 } 62 63 int ans; 64 65 void match(char word[]) 66 { 67 int i=0; 68 node *tmp=root; 69 while(word[i]) 70 { 71 int b=word[i]-'a'; 72 while(tmp!=NULL && tmp->next[b]==NULL) 73 tmp=tmp->fail; 74 if(tmp!=NULL) 75 { 76 tmp=tmp->next[b]; 77 node *t=tmp; 78 while(t!=NULL) 79 { 80 if(t->cnt>0) 81 { 82 ans+=t->cnt; 83 t->cnt=0; 84 } 85 t=t->fail; 86 } 87 } 88 else 89 tmp=root; 90 i++; 91 } 92 } 93 94 int main() 95 { 96 int cas,i; 97 //freopen("D:\\in.txt","r",stdin); 98 scanf("%d",&cas); 99 while(cas--) 100 { 101 memset(root,0,sizeof(struct node)); 102 num=1; 103 scanf("%d",&n); 104 for(i=0;i<n;i++) 105 { 106 scanf("%*c%s",str); 107 insert(str); 108 } 109 add_Fail(); 110 ans=0; 111 scanf("%*c%s",str); 112 match(str); 113 printf("%d\n",ans); 114 } 115 return 0; 116 }