您的位置:首页 > 其它

AC自动机 模板 hdu 2896

2013-04-19 15:20 417 查看


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=128;
struct node
{
node *fail;
node *next
;
int count;
node()
{
fail=NULL;
count=0;
memset(next,NULL,sizeof(next));
}
}*q[500005];
char key[205],model[10005];
int num[50005];
int head,tail;
void insert(char *s,node *root,int ant)
{
node *p = root;
int i = 0,k;
int len=strlen(s);
for(i = 0 ; i < len ; i ++)
{
k = s[i];
if(p->next[k] == NULL)
p->next[k] = new node();
p = p->next[k];
}
p->count=ant;
}
void build_fail(node *root)
{
int i;
q[tail ++] = root;
while(head != tail)
{
node *temp = q[head ++];
node *p=NULL;
for(i = 0 ; i < 128 ; i ++)
{
if(temp->next[i] != NULL)
{
if(temp == root)
temp->next[i]->fail=root;
else
{
p = temp->fail; //p指向当前结点的fail指针
while(p != NULL) //向根节点回溯,找父节点的fail指针指向的节点下有没有相等的前缀
{
if(p->next[i] != NULL) //找到相等的节点
{
temp->next[i]->fail = p->next[i]; //将fail指针指向想等的节点
break;
}
p = p->fail;//p指向自身的fail,如果p为root,p->fail为NULL,则p为NULL
}
if(p == NULL) //temp的fai指针指向的结点下没有相等的节点,fail指向root
temp->next[i]->fail = root;
}
q[tail ++] = temp->next[i];//下一个节点入队列
}
}
}
}
int query(node *root)
{
int i = 0,j=0,k,len = strlen(model);
//int flag = 0;
node *p = root;
for(i = 0 ; i < len ; i++)
{
k=model[i];
while(p != root && p->next[k] == NULL) //如果p指向的节点为NULL,p就指向它的fail指针
p = p->fail;
p = p->next[k];
p = (p == NULL) ? root : p; //如果p的next[k]为NULL,p就指回root,反之p指向next[k]
node *temp = p;
while(temp != root)
{
if(temp->count)
{
num[j ++] = temp->count;
}
temp=temp->fail;
}
}
//printf("~~~~~~~~~%d\n",j);
return j;
}
int main()
{
// freopen("Input.txt","r",stdin);
// freopen("Output.txt","w",stdout);
int n,m,i,j,k;
while(~scanf("%d",&n))
{
head=tail=0;
node *root = new node();
for(i = 1 ; i <= n ; i++)
{
scanf("%s",key);
insert( key , root , i);
}
build_fail(root);
scanf("%d",&m);
int total=0;
for(j = 1 ; j <= m; j++)
{
scanf("%s",model);
memset(num,0,sizeof(num));
k=query(root);
if(k)
{
printf("web %d:",j);
sort(num,num+k);
printf(" %d",num[0]);
for(i=1;num[i]!=0;i++)
{
if(num[i]!=num[i-1])
printf(" %d",num[i]);
}

printf("\n");
total++;
}
}
printf("total: %d\n",total);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: