AC自动机(指针查找是否存在)

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <cmath>
  6 #include <queue>
  7 using namespace std;
  8 const int maxn = 1000000+10;
  9 const int n = 26;
 10 char y[maxn];
 11 int result=0;
 12 
 13 struct Trie
 14 {
 15     Trie *next[n];
 16     int count1;
 17     Trie *fail;
 18     Trie()
 19     {
 20         fail=NULL;
 21         count1=0;
 22         for(int i=0;i<n;i++)
 23             next[i]=NULL;
 24     }
 25 };
 26 
 27 Trie *root;
 28 
 29 void buildTrie(char *str)
 30 {
 31     int len=strlen(str);
 32     Trie *p=root,*q;
 33     for(int i=0;i<len;i++)
 34     {
 35         int id=str[i]-'a';
 36         if(p->next[id]==NULL)
 37             p->next[id]=new Trie();
 38         p=p->next[id];
 39     }
 40     p->count1++;
 41 }
 42 
 43 void buildfail()
 44 {
 45     queue<Trie* > q;
 46     q.push(root);
 47     while(!q.empty())
 48     {
 49         Trie *p=q.front();q.pop();
 50         for(int i=0;i<n;i++)
 51         {
 52             if(p->next[i]!=NULL)
 53             {
 54                 if(p==root) p->next[i]->fail=root;
 55                 else{
 56                     Trie *temp=p->fail;
 57                     while(temp!=NULL){
 58                     if(temp->next[i]!=NULL){
 59                         p->next[i]->fail=temp->next[i];
 60                         break;
 61                     }
 62                     if(temp->next[i]==NULL)
 63                         temp=temp->fail;
 64                     }
 65                     if(temp==NULL)
 66                         p->next[i]->fail=root;
 67                 }
 68                 q.push(p->next[i]);
 69             }
 70         }
 71     }
 72 }
 73 
 74 int query(char *str)
 75 {
 76     int len = strlen(str);
 77     Trie *p=root;
 78     for(int i=0;i<len;i++)
 79     {
 80         int id=str[i]-'a';
 81         while(p->next[id]==NULL&&p!=root)
 82             p=p->fail;
 83         p=p->next[id];
 84         if(p==NULL)
 85             p=root;
 86         Trie *temp=p;
 87         while(temp!=root&&temp->count1!=-1)//扫后缀
 88         {
 89             result+=temp->count1;
 90             temp->count1=-1;
 91             temp=temp->fail;
 92         }
 93     }
 94     return result;
 95 }
 96 
 97 int  main()
 98 {
 99     int case1;
100     scanf("%d",&case1);
101     while(case1--)
102     {
103         result=0;
104         int n;
105         scanf("%d",&n);
106         root=new Trie();
107         while(n--)
108         {
109            char s[60];
110            scanf("%s",s);
111            buildTrie(s);
112         }
113         buildfail();
114         scanf("%s",y);
115         printf("%d\n",query(y));
116     }
117     return 0;
118 }

 

posted @ 2018-04-13 10:49  痞子熊  阅读(179)  评论(0编辑  收藏  举报