题意:
给定n个模式串
第n+1行给定文本串
问:
在文本串出现最多次的模式串 出现的次数和所有出现最多次的模式串(按字典序输出)
思路:
AC自动机模版题
#include<stdio.h>
#include<string.h>
#include<queue>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 1000010
#define maxnode 250001
#define sigma_size 26
struct node{
char ch[80];
}ans[200];
int top;
struct Trie{
int ch[maxnode][sigma_size];
int val[maxnode];
int last[maxnode];
int f[maxnode];
int num[maxnode];
int pre[maxnode];
int len[maxnode];
int Char[maxnode];
int sz;
void init(){
sz=1;
memset(ch,0,sizeof(ch));
memset(val, 0, sizeof(val));
memset(f,0,sizeof(f));
memset(last,0,sizeof(last)); //记录该节点前一个节点是谁
memset(len, 0, sizeof(len));
}
int idx(char c){ return c-'a'; }
void print(int j, char *s){
s[len[j]] = 0;
while(j){
s[len[j]-1] = Char[j];
j = pre[j];
}
}
int insert(char *s){
int u = 0;
for(int i = 0; s[i] ;i++){
int c = idx(s[i]);
if(!ch[u][c])
ch[u][c] = sz++;
pre[ch[u][c]] = u;
Char[ch[u][c]] = s[i];
len[ch[u][c]] = len[u]+1;
u = ch[u][c];
}
val[u] ++;
num[u] = 0;
return u;
}
void getFail(){
queue<int> q;
for(int i = 0; i<sigma_size; i++)
if(ch[0][i]) q.push(ch[0][i]);
while(!q.empty()){
int r = q.front(); q.pop();
for(int c = 0; c<sigma_size; c++){
int u = ch[r][c];
if(!u)continue;
q.push(u);
int v = f[r];
while(v && ch[v][c] == 0) v = f[v]; //沿失配边走上去 如果失配后有节点 且 其子节点c存在则结束循环
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
}
void find(char *T){
int j = 0;
for(int i = 0; T[i] ; i++){
int c = idx(T[i]);
while(j && ch[j][c]==0) j = f[j];
j = ch[j][c];
int temp = j;
while(temp){ //沿失配边走 || 若沿失配边走时一定要节点为单词结尾则改成while(temp && val[temp])
if(val[temp])num[temp]++;
temp = f[temp];
}
}
}
int bestnum(){
queue<int>q;
int best = 0;
for(int i = 0; i < sigma_size; i++)
{
if(ch[0][i])q.push(ch[0][i]);
if(val[ch[0][i]])best = max(best, num[ch[0][i]]);
}
while(!q.empty())
{
int r = q.front(); q.pop();
for(int c = 0; c < sigma_size; c++){
int u = ch[r][c];
if(!u)continue;
q.push(u);
if(val[u])best = max(best, num[u]);
}
}
return best;
}
void match(int best){
queue<int>q;
for(int i = 0; i < sigma_size; i++)
{
if(ch[0][i])q.push(ch[0][i]);
if(val[ch[0][i]] && num[ch[0][i]]==best)print(ch[0][i], ans[top++].ch);
}
while(!q.empty())
{
int r = q.front(); q.pop();
for(int c = 0; c < sigma_size; c++){
int u = ch[r][c];
if(!u)continue;
q.push(u);
if(val[u] && num[u] == best)print(u, ans[top++].ch);
}
}
}
};
Trie ac;
char s[1000006];
bool cmp(node a,node b){return strcmp(a.ch, b.ch)<0;}
int main(){
int n, i;
while(scanf("%d",&n), n){
ac.init();
for(i = 0; i < n; i++)scanf("%s", s), ac.insert(s);
ac.getFail();
scanf("%s", s);
ac.find(s);
int best = ac.bestnum();
printf("%d\n", best);
top=0;
ac.match(best);
sort(ans, ans+top, cmp);
for(i = 0; i < top; i++)printf("%s\n", ans[i].ch);
}
return 0;
}