AC自动机

去年就见到过这个词,不过一直没有去看,不是很理解其中的算法,可能是对kmp还没能够了解透彻。。

一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过。

要搞懂AC自动机,先得有模式树(字典树)TrieKMP模式匹配算法的基础知识。

AC自动机算法分为3步:构造一棵Trie树,构造失败指针和模式匹配过程。

详见:http://www.cppblog.com/mythit/archive/2009/04/21/80633.html     (AC自动机算法详解)

贴个模板吧:

hdu 2222 经典ac自动机

# include<stdio.h>

# include<queue>

# include<string.h>

# define MAX 26

using namespace std;

struct Trie{

	int count;

	struct Trie *next[MAX],*fail;

};

queue<Trie *>q;

char keyword[55];//记录单词

char str[1000005];//记录模式串 

Trie *NewTrie()

{

	int i;

	Trie *temp=new Trie;

	temp->count=0;

	for(i=0;i<MAX;i++)

		temp->next[i]=NULL;

	return temp;

}

void Insert(Trie *p,char s[])

{

	int i;

	Trie *temp=p;

	i=0;

	while(s[i])

	{

		if(temp->next[s[i]-'a']==NULL) temp->next[s[i]-'a']=NewTrie();

		temp=temp->next[s[i]-'a'];

		i++;

	}

	temp->count++;

}

void bulid_ac_automation(Trie *root)

{

	int i;

	q.push(root);

	root->fail=NULL;

	while(!q.empty())

	{

		Trie *temp=q.front();

		q.pop();

		Trie *p=NULL;

		for(i=0;i<MAX;i++)

		{

			if(temp->next[i]!=NULL)

			{

				if(temp==root) temp->next[i]->fail=root;

				else

				{

					p=temp->fail;

					while(p!=NULL)

					{

						if(p->next[i]!=NULL)

						{

							temp->next[i]->fail=p->next[i];

							break;

						}//if

						p=p->fail;

					}//while

					if(p==NULL) temp->next[i]->fail=root;

				}//else

				q.push(temp->next[i]);

			}//if

		}//for

	}//while

}//void

int query(Trie *root)

{

	int i,cnt,index,len;

	i=0;

	cnt=0;

	len=strlen(str);

	Trie *p=root;

	while(str[i])

	{

		index=str[i]-'a';

		while(p->next[index]==NULL && p!=root) p=p->fail;

		p=p->next[index];

		if(p==NULL) p=root;

		Trie *temp=p;

		while(temp!=root && temp->count!=-1)

		{

			cnt+=temp->count;

			temp->count=-1;

			temp=temp->fail;

		}

		i++;

	}

	return cnt;

}

int main()

{

	int i,n,ncase,cnt;

	Trie *p;

	scanf("%d",&ncase);

	while(ncase--)

	{

		p=NewTrie();

		scanf("%d",&n);

		for(i=1;i<=n;i++)

		{

			scanf("%s",keyword);

			Insert(p,keyword);

		}

		scanf("%s",str);

		bulid_ac_automation(p);

		cnt=query(p);

		printf("%d\n",cnt);

	}

	return 0;

}

你可能感兴趣的:(AC自动机)