HDU--3407[String-Matching Automata] AC自动机或kmp

 思路:弱化的AC自动机,也可以用KMP。

 

PS.在HDU能AC,在POJ一直WA、、、、

 

 

CODE:

/*AC自动机或kmp*/
/*AC代码:32ms*/
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
#include <queue>
#define MAXN 100006
#define kind 26
using namespace std;
char word[MAXN];//模式串
struct Node
{
	int next[kind],v,fail; 
}Trie[5*MAXN+10];
int snode;//字典树的总结点数(总状态数)
int N;//模式串数目
int cas;
void set_node(int x)
{
	memset(Trie[x].next,0,sizeof(Trie[x].next));
	Trie[x].v=0;//表示是否是危险结点
	Trie[x].fail=0; 
}
void Insert(char s[])
{
	int i=0,pos=0,index;
	int len=strlen(s);
	for(i=0;i<len;i++)
	{
		index=s[i]-'a';
		if(Trie[pos].next[index]==0)
		{
			set_node(++snode);
			Trie[pos].next[index]=snode; 
		}
		//if(Trie[pos].v)/*危险结点为其子结点不必继续(剪枝)*/
		//	break;
		pos=Trie[pos].next[index];
	}
	//Trie[pos].v++;
}
void Find_Fail(int pre,int ith,int now)
{
	if(!pre)//如果他的父节点是root,fail直接指向root 
	{ 
	 	Trie[now].fail=0;
	 	return;
	}
	int temp=Trie[pre].fail;
	while(temp!=-1)
	{
		if(Trie[temp].next[ith]!=0)
		{
			Trie[now].fail=Trie[temp].next[ith];
			//if(Trie[Trie[temp].next[ith]].v)//注意
			//	Trie[now].v++;
			return;
		}
		temp=Trie[temp].fail; 
	}
	if(temp==-1)
		Trie[now].fail=0;
	return; 
}
queue<int>Q;
void Build_AC_Fail()
{
	int i,pos;
	while(!Q.empty()) Q.pop(); 
	Trie[0].fail=-1; 
	Q.push(0); 
	while(!Q.empty())
	{
		pos=Q.front();Q.pop();
		for(i=0;i<kind;i++)
		{
			if(Trie[pos].next[i]!=0)//存在就要去找fail指针
			{
				Find_Fail(pos,i,Trie[pos].next[i]);
				Q.push(Trie[pos].next[i]);
			}
			else//让它的next指向pos的fail的next
				Trie[pos].next[i]=Trie[Trie[pos].fail].next[i];
		}
	}
}
void Solve()
{
	int i,j;
	set_node(0);snode=0;
	Insert(word);
	Build_AC_Fail();
	for(i=0;i<=snode;i++)
	{
		printf("%d",i);
		for(j=0;j<26;j++)
			printf(" %d",Trie[i].next[j]);
		printf("\n");
	}
}
int main()
{
	while(scanf("%s",word)!=EOF)
	{
		if(word[0]=='0') break;
		Solve();
	}
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__简言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值