网上讲解很多,其实自己可以模拟一遍,就能明白
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn=500010;
char str[1000050],key[55];
struct node
{
node *fail;
node *next[26];
int count;
char str[55];
node()
{
fail=NULL;
count=0;
memset(next,NULL,sizeof(next));
memset(str,0,sizeof(str));
}
};
node *root,*q[maxn];
int head,tail;
void InSert(char *str)
{
int i=0;
node *p=root;
while(str[i])
{
int id=str[i]-'a';
if(p->next[id]==NULL) p->next[id]=new node();
p=p->next[id];
i++;
}
p->count++;
}
void Build_ac_Bfs()
{
q[tail++]=root;
while(head!=tail)
{
node *p=q[head++];
node *tmp=NULL;
for(int i=0;i<26;i++)
{
if(p->next[i]==NULL) continue;
if(p==root) p->next[i]->fail=root;
else
{
tmp=p->fail;
while(tmp!=NULL)
{
if(tmp->next[i]!=NULL)
{
p->next[i]->fail=tmp->next[i];
break;
}
tmp=tmp->fail;
}
if(tmp==NULL) p->next[i]->fail=root;
}
q[tail++]=p->next[i];
}
}
}
int Query()
{
int id,len=strlen(str),res=0;
node *p=root;
for(int i=0;i<len;i++)
{
id=str[i]-'a';
while(p->next[id]==NULL&&p!=root) p=p->fail;
p=p->next[id];
if(p==NULL) p=root;
node *tmp=p;
while(tmp!=root&&tmp->count!=-1)
{
res+=tmp->count;
tmp->count=-1;
tmp=tmp->fail;
}
}
return res;
}
void Del(node *p)
{
for(int i=0;i<26;i++)
if(p->next[i]!=NULL)
Del(p->next[i]);
delete p;
}
int main()
{
//freopen("Input.txt","r",stdin);
int ncase,num;
scanf("%d",&ncase);
while(ncase--)
{
head=tail=0;
root=new node();
scanf("%d",&num);
getchar();
for(int i=0;i<num;i++)
{
gets(key);
InSert(key);
}
Build_ac_Bfs();
scanf("%s",str);
printf("%d\n",Query());
Del(root);
}
return 0;
}