思路:
注意从小到大,然后先标记,然后依次输出。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 205*500;
const int N = 130;
struct Tire{
int fail[maxn],end[maxn],nxt[maxn][N],vis[maxn],tot,root;
int newNode(){
for(int i=0;i<N;i++) nxt[tot][i] = -1;
end[tot++] = 0;
return tot-1;
}
void Init(){
tot = 0;
root = newNode();
}
void Insert(char *buf,int id){
int u = root,i,len = strlen(buf);
for(i=0;i<len;i++){
int k = buf[i];
if(nxt[u][k]==-1) nxt[u][k] = newNode();
u = nxt[u][k];
}
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 x = q.front();q.pop();
for(int i=0;i<N;i++){
if(nxt[x][i]==-1) nxt[x][i] = nxt[fail[x]][i];
else{
fail[nxt[x][i]] = nxt[fail[x]][i];
q.push(nxt[x][i]);
}
}
}
}
bool query(char *buf,int id,int n){
memset(vis,0,sizeof(vis));
int len = strlen(buf),fg = 0,now = root;
for(int i=0;i<len;i++){
int k = buf[i];
now = nxt[now][k];
int tmp = now;
while(tmp!=root){
if(end[tmp]!=0) vis[end[tmp]] = 1,fg = 1;
tmp = fail[tmp];
}
}
if(fg){
printf("web %d:",id);
for(int i=1;i<=n;i++)
if(vis[i]==1){
printf(" %d",i);
}
printf("\n");
return true;
}
return false;
}
};
Tire AC;
char ss[maxn];
int main(void)
{
int n,m,i,cnt;
while(~scanf("%d",&n)){
AC.Init();cnt = 0;
for(i=1;i<=n;i++){
scanf("%s",ss);
AC.Insert(ss,i);
}
AC.build();
scanf("%d",&m);
for(i=1;i<=m;i++){
scanf("%s",ss);
if(AC.query(ss,i,n)==true) cnt++;
}
printf("total: %d\n",cnt);
}
return 0;
}