#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define maxn 11000
#define sigma_size 26
char s[151][80], t[1000009];
struct ac
{
int ch[maxn][sigma_size];
int val[maxn], f[maxn], last[maxn];
int cnt[maxn];//计算子串出现的次数
int next;
void init()
{
next = 0;
memset(ch[0], 0, sizeof(ch[0]));
memset(val, 0, sizeof(val));
memset(cnt, 0, sizeof(cnt));
}
void insert(char *s, int v)
{
int len = strlen(s), cur = 0;
for (int i=0; i<len; i++)
{
int idx = s[i] - 'a';
if (!ch[cur][idx])
{
ch[cur][idx] = ++next;
memset(ch[next], 0, sizeof(ch[next]));
}
cur = ch[cur][idx];
}
val[cur] = v;
}
void getfail()
{
queue<int>q;
q.push(0);
while (!q.empty())
{
int cur = q.front();
q.pop();
for (int i=0; i<sigma_size; i++)
{
int u = ch[cur][i];
if (u)
{
if (cur==0)
f[u] = last[u] = 0;
else
{
int j = f[cur];
while (j && !ch[j][i])
j = f[j];
f[u] = ch[j][i];
last[u] = val[ f[u] ] ? f[u] : last[ f[u] ];
}
q.push(u);
}
else
ch[cur][i] = ch[ f[cur] ][i];
}
}
}
int find(char *t)
{
int len = strlen(t), temp, j = 0;
for (int i=0; i<len; i++)
{
int idx = t[i] - 'a';
j = ch[j][idx];
temp = j;
while (temp && val[temp])
{
cnt[ val[temp] ] ++;
//val[temp] = 0;//不注释掉匹配到的串只计算一次
temp = last[temp];
}
}
}
}ac;
int main()
{
int ncase, n, best;
while (scanf("%d", &n) == 1 && n)
{
ac.init();
for (int i=1; i<=n; i++)
{
scanf("%s", s[i]);
ac.insert(s[i], i);
}
ac.getfail();
scanf("%s", t);
ac.find(t);
best = -1;
for (int i=1; i<=n; i++)
if (ac.cnt[i] > best)
best = ac.cnt[i];
printf("%d\n", best);
for (int i=1; i<=n; i++)
if (ac.cnt[ i ]==best)
printf("%s\n", s[i]);
}
return 0;
}
LA 4670 ac自动机模板
最新推荐文章于 2022-05-10 19:11:21 发布