思路:
好题;
代码:
#include <queue> #include <cstdio> #include <cstring> using namespace std; #define maxn 50005 #define maxm 2000005 int ne[maxn][26],fail[maxn],tag[maxn],n,len[1005],tot,ans[1005]; char ch[maxm],vi[1005][55]; queue<int>que; int main() { int i,j,temp,now,pos; while(scanf("%d",&n)!=EOF) { memset(ne,0,sizeof(ne)); memset(ans,0,sizeof(ans)); memset(tag,0,sizeof(tag)); getchar(),tot=1; for(i=1;i<=n;i++) { now=1; gets(vi[i]),len[i]=strlen(vi[i]); for(j=0;j<len[i];j++) { pos=vi[i][j]-'A'; if(!ne[now][pos]) ne[now][pos]=++tot; now=ne[now][pos]; } tag[now]=i; } que.push(1); while(!que.empty()) { now=que.front(),que.pop(); for(i=0;i<26;i++) { if(!ne[now][i]) continue; else que.push(ne[now][i]); if(now==1) fail[ne[now][i]]=1; else { temp=fail[now]; while(temp) { if(ne[temp][i]) { fail[ne[now][i]]=ne[temp][i]; break; } temp=fail[temp]; } if(!temp) fail[ne[now][i]]=1; } } } now=1,gets(ch);int lit=strlen(ch); for(i=0;i<lit;i++) { pos=ch[i]-'A'; if(pos>=0&&pos<26) { if(ne[now][pos]) now=ne[now][pos]; else { temp=fail[now]; while(temp) { if(ne[temp][pos]) { now=ne[temp][pos]; break; } temp=fail[temp]; } if(!temp) now=1; } } else { now=1; continue; } temp=now; while(temp) { ans[tag[temp]]++; temp=fail[temp]; } } for(i=1;i<=n;i++) { if(ans[i]) { printf("%s: %d ",vi[i],ans[i]); } } } return 0; }