http://acm.hdu.edu.cn/showproblem.php?pid=2222
第一个AC自动机
AC自动机就是在trie上进行kmp
需要三个步骤
1,建立trie
2,求fail指针
3,匹配
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1000005;
const int K=26;
struct nodeTrie
{
nodeTrie()
{
v=0;
fail=NULL;
for(int i=0;i<K;++i)
next[i]=NULL;
}
int v;
struct nodeTrie *fail;
struct nodeTrie *next[K];
}*root;
char s[N];
void addWord(nodeTrie *p,char *s)
{
if(s[0]=='\0') return ;
for(int i=0;s[i]!='\0';++i)
{
if(p->next[s[i]-'a']==NULL)
p->next[s[i]-'a']=new nodeTrie;
p=p->next[s[i]-'a'];
}
++(p->v);
}
void init(int n)
{
root=new nodeTrie;
while(n--)
{
gets(s);
addWord(root,s);
}
}
void bfs(nodeTrie *p)
{
p->fail=root;
queue<nodeTrie *>qt;
qt.push(p);
while(!qt.empty())
{
nodeTrie *y;
nodeTrie *x=qt.front();qt.pop();
for(int i=0;i<K;++i)
if(x->next[i]!=NULL)
{
qt.push(x->next[i]);
if(x==root)
{x->next[i]->fail=root;continue;}
y=x->fail;
while(y!=root&&y->next[i]==NULL)
y=y->fail;
if(y->next[i]!=NULL)
x->next[i]->fail=y->next[i];
else
x->next[i]->fail=root;
}
}
}
int match(nodeTrie *p,char *s)
{
int wordCount=0;
int l=0;
while(s[l]!='\0')
{
while(p->next[s[l]-'a']==NULL&&p!=root)
p=p->fail;
if(p->next[s[l]-'a']!=NULL)
p=p->next[s[l]-'a'];
++l;
nodeTrie *fp=p;
while(fp!=root)
{
if((fp->v)>0) {wordCount+=(fp->v);fp->v=0;}
fp=fp->fail;
}
}
return wordCount;
}
int main()
{
//freopen("data.in","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d ",&n);
init(n);
bfs(root);
gets(s);
printf("%d\n",match(root,s));
}
return 0;
}
浙公网安备 33010602011771号