#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<set>
using namespace std;
const int maxn=52;
const int maxm=1000002;
char s[maxm],str[maxn];
int t,n,m,ans,res;
struct node
{
int idx,flag;
node *fail;
node *next[27];
node()
{
memset(next,0,sizeof(next));
idx=0;
flag=0;
fail=NULL;
}
};
void Insert(node *rt,char s[])
{
node *p=rt;
int i=0;
while(s[i])
{
int k=s[i++]-'a';
if(p->next[k]==NULL)p->next[k]=new node();
p=p->next[k];
}
p->flag=1;//字符串结尾
p->idx++;//代表第几个字符串
}
void build_AC(node *rt)
{
int i,j=0;
queue<node*>q;
rt->fail=NULL;
q.push(rt);
while(!q.empty())
{
node *p=q.front();
q.pop();
for(i=0;i<26;i++)
{
if(p->next[i]!=NULL)//寻找当前子树的失败指针
{
if(p==rt)
{
p->next[i]->fail=rt;
}else
{
node *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=rt;//无法获取,当前子树的失败指针为根
}
q.push(p->next[i]);
}
}
}
}
int query_AC(node *rt,char s[])
{
int i=0,j;
ans=0;
node *p=rt;
while(s[i])
{
int k=s[i++]-'a';
while(p->next[k]==NULL&&p!=rt)p=p->fail;//失配
p=p->next[k];
if(p==NULL)p=rt;//失配指针为根
node *tmp=p;
while(tmp!=rt&&tmp->idx>0)
{
ans+=tmp->idx;
tmp->idx=-1;
tmp=tmp->fail;
}
}
return ans;
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
int i,j;
node *rt=new node();
for(i=1; i<=n; i++)
{
scanf("%s",&str);
Insert(rt,str);
}
build_AC(rt);
scanf("%s",s);
int res=query_AC(rt,s);
cout<<res<<endl;
}
return 0;
}
hdu 2222 史上最裸 AC自动机
最新推荐文章于 2019-08-14 06:47:07 发布