题意:给许多字符串和一个文本串,问你出现最多的次数及哪些字符串出现了这些次
思路:直接套模版,然后注意一下有可能有相同的字符串,在AC自动机中后面的会覆盖前面的,那么用map处理一下即可
#include <map>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1000010;
const int N=26;
struct node{
node *fail;
node *next[N];
int num;
node(){
fail=NULL;
num=0;
memset(next,NULL,sizeof(next));
}
}*q[maxn];
char str1[160][80],str2[maxn];
map<string,int>ms;
int head,tail,cnt[maxn];
void insert_Trie(char *str,node *root,int iddd){
node *p=root;
int i=0;
while(str[i]){
int id=str[i]-'a';
if(p->next[id]==NULL) p->next[id]=new node();
p=p->next[id];i++;
}
p->num=iddd+1;
ms[string(str)]=iddd;
}
void build_ac(node *root){
root->fail=NULL;
q[head++]=root;
while(head!=tail){
node *temp=q[tail++];
node *p=NULL;
for(int i=0;i<N;i++){
if(temp->next[i]!=NULL){
if(temp==root) temp->next[i]->fail=root;
else{
p=temp->fail;
while(p!=NULL){
if(p->next[i]!=NULL){
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL) temp->next[i]->fail=root;
}
q[head++]=temp->next[i];
}
}
}
}
void query(node *root){
int i=0;
node *p=root;
while(str2[i]){
int id=str2[i]-'a';
while(p->next[id]==NULL&&p!=root) p=p->fail;
p=p->next[id];
p=(p==NULL)?root:p;
node *temp=p;
while(temp!=root&&temp->num!=0){
cnt[ms[string(str1[temp->num-1])]]++;
temp=temp->fail;
}
i++;
}
}
int main(){
int T,n;
while(scanf("%d",&n)!=-1){
if(n==0) break;
memset(cnt,0,sizeof(cnt));
node *root=new node();
head=tail=0;
for(int i=0;i<n;i++){
scanf("%s",str1[i]);
insert_Trie(str1[i],root,i);
}
build_ac(root);
scanf("%s",str2);query(root);
int max1=0;
for(int i=0;i<n;i++) if(cnt[ms[string(str1[i])]]>max1) max1=max(max1,cnt[ms[string(str1[i])]]);
printf("%d\n",max1);
for(int i=0;i<n;i++) if(cnt[ms[string(str1[i])]]==max1) printf("%s\n",str1[i]);
}
return 0;
}