AC自动机模板

学习链接:

http://www.cppblog.com/mythit/archive/2009/04/21/80633.html

http://blog.csdn.net/niushuai666/article/details/7002736

http://www.cnblogs.com/kuangbin/category/402395.html

 

hdu 2222 代码:

  1 #include <vector>
  2 #include <map>
  3 #include <set>
  4 #include <algorithm>
  5 #include <iostream>
  6 #include <cstdio>
  7 #include <cmath>
  8 #include <cstdlib>
  9 #include <string>
 10 #include <cstring>
 11 #include <queue>
 12 #include <stack>
 13 using namespace std;
 14 
 15 #define N 1000010
 16 
 17 char str[N],key[111];
 18 int head,tail;
 19 
 20 struct node
 21 {
 22     node *fail;
 23     node *next[26];
 24     int count;
 25     node(){
 26         fail=NULL;
 27         count=0;
 28         for(int i=0; i<26; i++)
 29             next[i]=NULL;
 30     }
 31 }*q[N];
 32 
 33 node *root;
 34 
 35 void insert(char *str)  //建立Trie  
 36 {
 37     int temp,len;
 38     node *p=root;
 39     len=strlen(str);
 40     for(int i=0; i<len; i++){
 41         temp=str[i]-'a';
 42         if(p->next[temp] == NULL)
 43             p->next[temp]=new node();
 44         p=p->next[temp];
 45     }
 46     p->count++;
 47 }
 48 
 49 void build_ac()   //初始化fail指针,BFS  
 50 {
 51     q[tail++]=root;
 52     while(head != tail){
 53         node *p=q[head++];  //弹出队头  
 54         node *temp=NULL;
 55         for(int i=0; i<26; i++){
 56             if(p->next[i] != NULL){
 57                 if(p==root)  //第一个元素fail必指向根  
 58                     p->next[i]->fail=root;
 59                 else{
 60                     temp=p->fail;   //失败指针
 61                     while(temp!=NULL){   //2种情况结束:匹配为空or找到匹配
 62                         if(temp->next[i]!=NULL){    //找到匹配
 63                             p->next[i]->fail=temp->next[i];
 64                             break;
 65                         }
 66                         temp=temp->fail;
 67                     }
 68                     if(temp==NULL)   //为空则从头匹配 
 69                         p->next[i]->fail=root;
 70                 }
 71                 q[tail++]=p->next[i];   //入队 
 72             }
 73         }
 74     }
 75 }
 76 
 77 int query()    //扫描
 78 {
 79     int index,len,ans=0;
 80     node *p=root;   //Tire入口
 81     len=strlen(str);
 82     for(int i=0; i<len; i++){
 83         index=str[i]-'a';
 84         while(p->next[index]==NULL && p!=root)  //跳转失败指针 
 85             p=p->fail;
 86         p=p->next[index];
 87         if(p==NULL)
 88             p=root;
 89         node *temp=p;   //p不动,temp计算后缀串 
 90         while(temp!=root && temp->count!=-1){
 91             ans+=temp->count;
 92             temp->count=-1;
 93             temp=temp->fail;
 94         }
 95     }
 96     return ans;
 97 }
 98 
 99 int main()
100 {
101     int t,num;
102     scanf("%d",&t);
103     while(t--){
104         head=tail=0;
105         root=new node();
106         scanf("%d",&num);
107         //getchar();
108         for(int i=0; i<num; i++){
109             scanf("%s",key);
110             insert(key);
111         }
112         build_ac();
113         scanf("%s",str);
114         printf("%d\n",query());
115     }
116 }

 

posted @ 2016-05-12 09:45  Vmetrio  阅读(151)  评论(0编辑  收藏  举报