RT.
#include <iostream>
#include <stdarg.h>
using namespace std;
const int kind=26;
struct node{
node* fail;
node* next[kind];
int count;//是否为该单词的最后一个节点
node(){
fail=NULL;
count=0;
memset(next,NULL,sizeof(next));
}
} *q[500001];//队列
char keyword[51];
char str[1000001];
int head,tail;//队列的头尾指针
void insert(char *str,node *root)//构造trie树
{
node *temp=root;
int i=0;
while(str[i])
{
if(temp->next[str[i]-'a']==NULL) temp->next[str[i]-'a']=new node();
temp=temp->next[str[i]-'a'];
i++;
}
temp->count++;
}
void build_ac_automation(node *root)//构造fail指针
{
q[0]=root;
root->fail=NULL;
head=0;tail=1;
while(head!=tail)
{
for(int i=0;i<kind;i++)
{
if(q[head]->next[i]!=NULL)
{
q[tail++]=q[head]->next[i];
node* temp=q[head];
while(temp->fail!=NULL)
{
if(temp->fail->next[i]!=NULL)
{
q[head]->next[i]->fail=temp->fail->next[i];
break;
}
temp=temp->fail;
}
if(temp->fail==NULL)
q[head]->next[i]->fail=root;
}
}
head++;
}
}
int query(node* root)//查询过程
{
int i=0, count=0,index,len=strlen(str);
node *temp=root;
while(str[i])
{
while(temp!=NULL&&temp->next[str[i]-'a']==NULL)
temp=temp->fail;
if(temp!=NULL)
{
temp=temp->next[str[i]-'a'];
node *temp2=temp;
while(temp2->fail!=NULL)
{
if(temp2->count>=1)
{
count+=temp2->count;
temp2->count=-1;
}
temp2=temp2->fail;
}
}
else
{
temp=root;
}
i++;
}
return count;
}
int main()
{
int n;
int g;
scanf("%d",&g);
for(int i=0;i<g;i++)
{
node *root=new node();
scanf("%d",&n);
getchar();
while(n--){
gets(keyword);
insert(keyword,root);
}
build_ac_automation(root);
scanf("%s",str);
printf("%d\n",query(root));
}
return 0;
}
/**
易错测试数据
1
h
hhhhh
结果是1,因为只有一个关键字h,而字符串中出现了4次h,但是算做重复,只计数一次
2
a
a
a
结果是2,因为keywords中a 出现了两次
*/