Code:
#include<cstdio> //Aho Corasick Automaton #include<cstring> #include<queue> using namespace std; const int maxn=1000000+3; const int maxd=20000+3; const int sigma=30; char S[maxn],A[160][80]; int mapp[152],times[maxd],val[maxd],last[maxd],f[maxd]; int cnt=0,ans; queue<int>Q; struct node{int next[30];}ch[maxd]; int idx(char a){return a-'a';} struct V{ void insert(char p[],int id){ int n=strlen(p),cur=0; for(int i=0;i<n;++i){ int u=idx(p[i]); if(!ch[cur].next[u])ch[cur].next[u]=++cnt; cur=ch[cur].next[u]; } ++val[cur],mapp[id]=cur; } void getfail(){ for(int i=0;i<sigma;++i)if(ch[0].next[i])Q.push(ch[0].next[i]); while(!Q.empty()){ int r=Q.front(); Q.pop(); for(int i=0;i<sigma;++i){ int u=ch[r].next[i]; if(!u){ch[r].next[i]=ch[f[r]].next[i];continue;} Q.push(u);int v=f[r]; f[u]=ch[v].next[i]; last[u]=val[f[u]]?f[u]:last[f[u]]; } } } void print(int j){ if(j){ if(val[j]){++times[j];ans=max(ans,times[j]);} if(last[j]){ print(last[j]); } } } void Automaton(char T[]){ int n=strlen(T);int j=0; for(int i=0;i<n;++i){ int c=idx(T[i]); j=ch[j].next[c]; print(j); } } }AC; int main(){ while(1){ int n;scanf("%d",&n);if(!n)return 0; memset(ch,0,sizeof(ch)); memset(val,0,sizeof(val)); memset(last,0,sizeof(last)); memset(f,0,sizeof(f)); memset(times,0,sizeof(times)); cnt=0,ans=0; for(int i=1;i<=n;++i){scanf("%s",A[i]);AC.insert(A[i],i);} scanf("%s",S); AC.getfail(); AC.Automaton(S); printf("%d ",ans); for(int i=1;i<=n;++i) if(times[mapp[i]]==ans)printf("%s ",A[i]); } return 0; }