【模板】AC自动机(加强版)

题目描述

个由小写字母组成的模式串以及一个文本串。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串中出现的次数最多。

输入输出格式

输入格式:

 

输入含多组数据。

每组数据的第一行为一个正整数,表示共有个模式串,

接下去行,每行一个长度小于等于的模式串。下一行是一个长度小于等于的文本串

输入结束标志为

 

输出格式:

 

对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。

 

输入输出样例

输入样例#1:
2
aba
bab
ababababac
6
beta
alpha
haha
delta
dede
tata
dedeltalphahahahototatalpha
0
输出样例#1:
4
aba
2
alpha
haha

个人认为没有什么特别大的变化,记录一下,然后简单运用一下,就ok了,纯裸题,不过用c++自带的queue貌似有些慢,
应该可以优化一下。
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<queue>
 7 using namespace std;
 8 
 9 int n,cnt=1,fzy[157];
10 char s[157][77];
11 struct Node
12 {
13     int c[26],suf,flag,mark;
14     void init()
15     {
16         suf=flag=mark=0;
17         memset(c,0,sizeof(c));    
18     }    
19 }tree[1000007];
20 
21 void init()
22 {
23     memset(fzy,0,sizeof(fzy));
24     for (int i=0;i<=cnt;i++)
25         tree[i].init();
26     cnt=1;    
27 }
28 void Ins(int num)
29 {
30     int head=1,l=strlen(s[num]);
31     for (int i=0;i<l;i++)
32     {
33         int now=s[num][i]-'a';
34         if (!tree[head].c[now]) tree[head].c[now]=++cnt;
35         head=tree[head].c[now];
36     }
37     tree[head].flag++,tree[head].mark=num;
38 }
39 void Make_AC()
40 {
41     for (int i=0;i<26;i++) tree[0].c[i]=1;
42     int head=0,tail=1;
43     queue<int>q;
44     while (!q.empty()) q.pop();
45     tree[1].suf=0;
46     q.push(1);
47     while (!q.empty())
48     {
49         int u=q.front();
50         q.pop();
51         for (int i=0;i<26;i++)
52             if (tree[u].c[i])
53             {
54                 tree[tree[u].c[i]].suf=tree[tree[u].suf].c[i];
55                 q.push(tree[u].c[i]);
56             }
57             else tree[u].c[i]=tree[tree[u].suf].c[i];
58     }
59 }
60 void Solve()
61 {
62     char s1[1000007];
63     scanf("%s",s1);
64     int head=1,len=strlen(s1);
65     for (int i=0;i<len;i++)
66     {
67         int now=s1[i]-'a';
68         head=tree[head].c[now];
69         for (int j=head;j&&tree[j].flag!=-1;j=tree[j].suf)
70             fzy[tree[j].mark]+=tree[j].flag;
71     }
72     int x=fzy[1];
73     for (int i=2;i<=n;i++)
74         if (x<fzy[i]) x=fzy[i];
75     printf("%d\n",x);    
76     for (int i=1;i<=n;i++) 
77         if (x==fzy[i]) printf("%s\n",s[i]);
78 }
79 int main()
80 {    
81     while (scanf("%d",&n)&&n)
82     {
83         init();
84         for (int i=1;i<=n;i++)
85             {scanf("%s",s[i]);Ins(i);}
86         Make_AC();
87         Solve();
88     }
89 }

 

 
posted @ 2017-07-26 20:34  Kaiser-  阅读(196)  评论(0编辑  收藏  举报