题目描述
有NN个由小写字母组成的模式串以及一个文本串TT。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串TT中出现的次数最多。
输入输出格式
输入格式:
输入含多组数据。
每组数据的第一行为一个正整数NN,表示共有NN个模式串,1 \leq N \leq 1501≤N≤150。
接下去NN行,每行一个长度小于等于7070的模式串。下一行是一个长度小于等于10^6106的文本串TT。
输入结束标志为N=0N=0。
输出格式:
对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。
输入输出样例
输入样例#1:
2
aba
bab
ababababac
6
beta
alpha
haha
delta
dede
tata
dedeltalphahahahototatalpha
0
输出样例#1:
4
aba
2
alpha
haha
模板题
#include <bits/stdc++.h>
using namespace std;
int const N = 105000 + 10;
int const M = 150 + 10;
int const INF = 0x7f7f7f7f;
struct Node{
Node *next[26];
Node *fail;
int num;
Node(){
memset(next,NULL,sizeof(next));
fail = NULL;
num = 0; //0表示这个模式串未出现,出现了用相应得编号代替;
}
}*p[N];
Node *root;
map<string,int>mp;
map<int,string>mp2;
int n;
int val[N];
void Insert(string s,int number){
Node *now = root;
for(int i=0;i<s.length();i++){
int to = s[i] - 'a';
if(now->next[to] == NULL)
now->next[to] = new Node();
now = now->next[to];
}
now->num = number;
}
void Get_Fail(){
int head = 0,tail = 0;
root->fail = NULL;
p[head++] = root;
while(head != tail){
Node *q = p[tail++];
Node *tmp;
for(int i=0;i<26;i++){
if(q->next[i] == NULL) continue;
if(q == root) q->next[i]->fail = root;
else{
tmp = q->fail;
while(tmp){
if(tmp->next[i]){
q->next[i]->fail = tmp->next[i];
break;
}
tmp = tmp->fail;
}
if(tmp == NULL) q->next[i]->fail = root;
}
p[head++] = q->next[i];
}
}
}
int Match(string s){
Node *tmp,*p = root;
int ans = -INF;
for(int i=0;i<s.length();i++){
int to = s[i] - 'a';
while(p && p->next[to] == NULL) p = p->fail;
if(p) p = p->next[to];
else p = root;
tmp = p;
while(tmp != root){
if(tmp->num) //判断是否是结点末尾
ans = max(ans,++val[tmp->num]);
tmp = tmp->fail; //沿着fail指针回去,找到跟短的后缀
}
}
return ans;
}
void Print(int ans){
cout<<ans<<endl;
for(int i=1;i<=n;i++){
if(val[i] == ans)
cout<<mp2[i]<<endl;
}
}
int main(){
ios::sync_with_stdio(false);
while(cin>>n&&n){
mp.clear();
mp2.clear();
root = new Node();
memset(val,0,sizeof(val));
for(int i=1;i<=n;i++){
string s;
cin>>s;
if(mp[s]) continue; //去重
mp[s] = i;
mp2[i] = s;
Insert(s,i);
}
string str;
cin>>str;
Get_Fail();
int ans = Match(str);
Print(ans);
}
return 0;
}
/*每个模式串给它一个编号*/