AC自动机 模板 hdu 2896

AC自动机 模板 hdu 2896_第1张图片

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=128;
struct node
{
	node *fail;
	node *next[N];
	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;
}


你可能感兴趣的:(AC自动机 模板 hdu 2896)