HDU 2222 Keywords Search(AC自动机模板题)

http://acm.hdu.edu.cn/showproblem.php?pid=2222

题意:
给出多个单词,最后再给出一个模式串,求在该模式串中包含了多少个单词。

思路:

AC自动机的模板题。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<vector>
  6 #include<stack>
  7 #include<queue>
  8 #include<cmath>
  9 #include<map>
 10 #include<set>
 11 using namespace std;
 12 typedef long long ll;
 13 const int INF = 0x3f3f3f3f;
 14 const int maxn=10000+5;
 15 
 16 int n;
 17 int num;
 18 
 19 struct Trie
 20 {
 21     int son[30];
 22     int cnt;
 23     int fail;
 24 }t[100*maxn];
 25 
 26 void init(int x)
 27 {
 28     t[x].cnt=t[x].fail=0;
 29     memset(t[x].son,0,sizeof(t[x].son));
 30 }
 31 
 32 void trie(char *s)
 33 {
 34     int n=strlen(s);
 35     int x=0;
 36     for(int i=0;i<n;i++)
 37     {
 38         int c=s[i]-'a'+1;
 39         if(!t[x].son[c])
 40         {
 41             num++;
 42             init(num);
 43             t[x].son[c]=num;
 44         }
 45         x=t[x].son[c];
 46     }
 47     t[x].cnt++;
 48 }
 49 
 50 void buildAC()
 51 {
 52     queue<int> Q;
 53     for(int i=1;i<=26;i++)  if(t[0].son[i])  Q.push(t[0].son[i]);
 54     while(!Q.empty())
 55     {
 56         int x=Q.front(); Q.pop();
 57         int fail=t[x].fail;
 58         for(int i=1;i<=26;i++)
 59         {
 60             int y=t[x].son[i];
 61             if(y)
 62             {
 63                 t[y].fail=t[fail].son[i];
 64                 Q.push(y);
 65             }
 66             else t[x].son[i]=t[fail].son[i];
 67         }
 68     }
 69 }
 70 
 71 int query(char *s)
 72 {
 73     int n=strlen(s);
 74     int x=0, ans=0;
 75     for(int i=0;i<n;i++)
 76     {
 77         int c=s[i]-'a'+1;
 78         while(x && !t[x].son[c])  x=t[x].fail;
 79         x=t[x].son[c];
 80         int tmp=x;
 81         while(tmp && t[tmp].cnt!=-1)
 82         {
 83             ans+=t[tmp].cnt;
 84             t[tmp].cnt=-1;
 85             tmp=t[tmp].fail;
 86         }
 87     }
 88     return ans;
 89 }
 90 
 91 int main()
 92 {
 93     //freopen("in.txt","r",stdin);
 94     int T;
 95     char s[1000005];
 96     scanf("%d",&T);
 97     while(T--)
 98     {
 99         num=0;
100         init(0);
101         scanf("%d",&n);
102         for(int i=0;i<n;i++)
103         {
104             scanf("%s",s);
105             trie(s);
106         }
107         buildAC();
108         scanf("%s",s);
109         printf("%d
",query(s));
110     }
111     return 0;
112 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7435325.html