#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string.h>
#include <queue> //AC自动机模板题(动态建立) hdu2896
using namespace std;
char a[205], b[10010];
int h, c[10];
struct trie
{
trie *next[128];
trie *fail; //失败指针,类似于kmp中的next
int g;
trie()
{
for(int t=0; t<128; ++t)
next[t]=NULL;
fail=NULL;
g=0;
}
}*root;
void create(char *p, int num) //建立字典树
{
int t=0, k, j=strlen(p);
trie *q=root;
while(t<j)
{
k=p[t]-31;
if(!q->next[k])
{
q->next[k]=new trie();
}
q=q->next[k];
t++;
}
q->g=num;
return ;
}
void makefail() //fail指针
{
queue<trie *> q;
q.push(root);
while(!q.empty())
{
trie *p=q.front(), *temp;
q.pop();
for(int t=0; t<128; ++t)
{
if(p->next[t])
{
temp=p;
if(p==root)
{
temp->next[t]->fail=p;
}
else
{
while(temp->fail)
{
if(temp->fail->next[t])
{
p->next[t]->fail=temp->fail->next[t];
break;
}
temp=temp->fail;
}
if(!temp->fail)
{
p->next[t]->fail=root;
}
}
q.push(p->next[t]);
}
}
}
return ;
}
void f(char *p)
{
int t, k, j=strlen(p);
trie *q=root, *temp;
h=0;
for(t=0; t<j; ++t)
{
k=p[t]-31;
while(q!=root&&q->next[k]==NULL)
{
q=q->fail;
}
q=q->next[k];
if(!q)q=root;
temp=q;
while(temp!=root&&temp->g)
{
c[h++]=temp->g; //修改的部分,前面都是模板
temp=temp->fail; //返回到temp的fail指针
}
}
return ;
}
int main()
{
int n, t, T, s, j;
while(scanf("%d", &n)!=EOF)
{
root=new trie();
for(t=1; t<=n; ++t)
{
scanf("%s", a);
create(a, t);
}
scanf("%d", &T);
makefail();
for(j=s=0; j<T; ++j)
{
scanf("%s", b);
f(b);
if(h)
{
printf("web %d: ", j+1);
sort(c, c+h);
for(t=0; t<h-1; ++t)
printf("%d ", c[t]);
printf("%d\n", c[t]);
s++;
}
}
printf("total: %d\n", s);
}
return 0;
}
hdu2896 AC自动机
最新推荐文章于 2020-09-14 19:28:55 发布