给你N个单词,给你一篇文章,问给出的单词在文章中出现的次数。
AC自动机基础题。模板题。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define N 500010
int head,tail;
char s[1000010],ss[100];
struct node{
node *fail;
node *next[26];
int num;
node()
{
fail=NULL;
num=0;
for(int i=0;i<26;i++)
next[i]=NULL;
}
}*q[N];
node *root;
void insert(char *s)
{
int i,j;
int m,l;
node *p=root;
l=strlen(s);
for(i=0;i<l;i++)
{
m=s[i]-'a';
if(p->next[m]==NULL)
p->next[m]=new node();
p=p->next[m];
}
p->num++;
}
void build_ac()
{
int i,j;
q[tail++]=root;
while(head!=tail)
{
node *p=q[head++];
node *temp=NULL;
for(i=0;i<26;i++)
{
if(p->next[i]!=NULL)
{
if(p==root)
p->next[i]->fail=root;
else
{
temp=p->fail;
while(temp!=NULL)
{
if(temp->next[i]!=NULL)
{
p->next[i]->fail=temp->next[i];
break;
}
temp=temp->fail;
}
if(temp==NULL)
p->next[i]->fail=root;
}
q[tail++]=p->next[i];
}
}
}
}
int query()
{
int i,id,l,sum;
node *p=root;
sum=0;
l=strlen(s);
for(i=0;i<l;i++)
{
id=s[i]-'a';
while(p->next[id]==NULL&&p!=root)
p=p->fail;
p=p->next[id];
if(p==NULL)
p=root;
node *temp=p;
while(temp!=root&&temp->num!=-1)
{
sum+=temp->num;
temp->num=-1;
temp=temp->fail;
}
}
return sum;
}
int main(void)
{
int i,j,k,n,m;
scanf("%d",&n);
while(n--)
{
head=tail=0;
root=new node();
scanf("%d",&m);
getchar();
for(i=0;i<m;i++)
{
gets(ss);
insert(ss);
}
build_ac();
scanf("%s",s);
printf("%d\n",query());
}
return 0;
}