思路:
考虑所有的ASCII字符的情况,用26范围内可能出错。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 1010*50;
const int MX = 2e6+10;
const int N = 130;
char ss[1005][55];
struct Tire{
int nxt[maxn][N],fail[maxn],end[maxn],tot,root,vis[maxn];
int newNode(){
for(int i=0;i<130;i++) nxt[tot][i] = -1;
end[tot++] = 0;
return tot-1;
}
void Init(){
tot = 0;
root = newNode();
}
void Insert(char *buf,int id){
int len = strlen(buf),i,u = root;
for(i=0;i<len;i++){
int x = buf[i];
if(nxt[u][x]==-1) nxt[u][x] = newNode();
u = nxt[u][x];
}
end[u] = id;
}
void build(){
queue <int> q;
fail[root] = root;
for(int i=0;i<N;i++){
if(nxt[root][i]==-1) nxt[root][i] = root;
else{
fail[nxt[root][i]] = root;
q.push(nxt[root][i]);
}
}
while(!q.empty()){
int now = q.front();
q.pop();
for(int i=0;i<N;i++){
if(nxt[now][i]==-1) nxt[now][i] = nxt[fail[now]][i];
else{
fail[nxt[now][i]] = nxt[fail[now]][i];
q.push(nxt[now][i]);
}
}
}
}
void query(char *buf,int n){
memset(vis,0,sizeof(vis));
int len = strlen(buf),now = root;
for(int i=0;i<len;i++){
int x = buf[i];
now = nxt[now][x];
int tmp = now;
while(tmp!=root){
if(end[tmp]!=0) vis[end[tmp]]++;
tmp = fail[tmp];
}
}
for(int i=1;i<=n;i++)
if(vis[i]>0){
printf("%s: %d\n",ss[i],vis[i]);
}
}
};
Tire AC;
char s1[MX];
int main(void){
int T,n,i,j;
while(scanf("%d",&n)==1){
AC.Init();
for(i=1;i<=n;i++){
scanf("%s",ss[i]);
AC.Insert(ss[i],i);
}
AC.build();
scanf("%s",s1);
AC.query(s1,n);
}
return 0;
}