http://acm.hdu.edu.cn/showproblem.php?pid=3065
AC自动机
代码:
#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=1005;
const int M=505;
const int K=26;
struct nodeTrie
{
nodeTrie()
{
v=0;
fail=NULL;
for(int i=0;i<K;++i)
next[i]=NULL;
}
int v;
nodeTrie *fail;
nodeTrie *next[K];
}*root;
char s[N][55];
char web[2000005];
int num[N];
void addWord(nodeTrie *p,char *s,int k)
{
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)=k;
}
void init(int n)
{
root=new nodeTrie;
for(int i=1;i<=n;++i)
{
gets(s[i]);
addWord(root,s[i],i);
}
}
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')
{
if(s[l]<'A'||s[l]>'Z') {p=root;++l;continue;}
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)
++num[fp->v];
fp=fp->fail;
}
}
return wordCount;
}
int main()
{
//freopen("data.in","r",stdin);
int n;
while(scanf("%d ",&n)!=EOF)
{
init(n);
bfs(root);
gets(web);
memset(num,0,sizeof(num));
match(root,web);
for(int i=1;i<=n;++i)
if(num[i]>0)
printf("%s: %d\n",s[i],num[i]);
}
return 0;
}