AC自动机(查找子串各出现次数)

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <string>
  5 #include <cstdio>
  6 #include <queue>
  7 #include <algorithm>
  8 #include <functional>
  9 #include <map>
 10 using namespace std;
 11 #define lson  (i<<1)
 12 #define rson  ((i<<1)|1)
 13 typedef long long ll;
 14 typedef unsigned int ul;
 15 const int  maxn = 40010;
 16 const int mod = 10007;
 17 int ans[1005];
 18 int tot;
 19 struct Tire
 20 {
 21     int nex[1000*55][130],fail[1000*55],ed[1000*55];
 22     int root,L;
 23     int newnode()
 24     {
 25         for(int i = 0; i < 130; i++)
 26             nex[L][i] = -1;
 27         ed[L++] = 0;
 28         return L-1;
 29     }
 30  
 31     void ini()
 32     {
 33         L = 0,root = newnode();
 34     }
 35  
 36     void inser(char buf[],int id)
 37     {
 38         int len = strlen(buf);
 39         int now = root;
 40         for(int i = 0; i < len; i++)
 41         {
 42             int ta = buf[i];
 43             if(nex[now][ta] == -1)
 44                 nex[now][ta] = newnode();
 45             now = nex[now][ta];
 46         }
 47         ed[now] = id;
 48     }
 49  
 50     void build()
 51     {
 52         queue<int >q;
 53         fail[root] = root;
 54         for(int i = 0; i < 130; i++)
 55             if(nex[root][i] == -1)
 56                 nex[root][i] = root;
 57             else
 58             {
 59                 fail[nex[root][i]] = root;
 60                 q.push(nex[root][i]);
 61             }
 62         while(!q.empty())
 63         {
 64             int now = q.front();
 65             q.pop();
 66             for(int i = 0; i < 130; i++)
 67             {
 68                 if(nex[now][i] == -1)
 69                     nex[now][i] = nex[fail[now]][i];
 70                 else
 71                 {
 72                     fail[nex[now][i]] = nex[fail[now]][i];
 73                     q.push(nex[now][i]);
 74                 }
 75             }
 76         }
 77     }
 78  
 79     void query(char buf[])
 80     {
 81         tot = 0;
 82         int cur = root;
 83         int len = strlen(buf);
 84         for(int i = 0; i < len; i++)
 85         {
 86             cur = nex[cur][(int)buf[i]];
 87             int tp = cur;
 88  
 89             while(tp != root)
 90             {
 91                 if(ed[tp])
 92                     ans[ed[tp]]++;
 93                 tp = fail[tp];
 94             }
 95         }
 96     }
 97 };
 98  
 99 Tire ac;
100 char buf[505][80];
101 char to[1000100];
102 int main()
103 {
104     int n;
105     while(scanf("%d",&n) != EOF)
106     {
107         if(n==0) break;
108         ac.ini();
109         for(int i = 1; i <= n; i++)
110         {
111             scanf("%s",buf[i]);
112             ac.inser(buf[i],i);
113         }
114         ac.build();
115         memset(ans,0,sizeof(ans));
116         scanf("%s",to);
117         ac.query(to);
118          int Max=0;
119         for(int i = 1; i <= n; i++)
120         {
121             Max=max(Max,ans[i]);
122         }
123         cout<<Max<<endl;
124         for(int i=1;i<=n;i++){
125             if(Max==ans[i]) cout<<buf[i]<<endl;
126         }
127         
128     }
129     return 0;
130 }

 

转载于:https://www.cnblogs.com/Culion-BEAR/p/8886147.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值