ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

学习笔记:AC-automation(AC自动机)

2021-08-20 08:00:07  阅读:237  来源: 互联网

标签:AC int automation str fail 自动机 size


  简单提一下起源好了:这个东西最早出现于贝尔实验室,是很常用的多模式匹配算法(对比于\(KMP\)的单模式串匹配)
  算法基础是\(Trie\)与\(KMP\)思想(只有思想)。
  AC自动机通俗的讲是Trie上的KMP。
  比较重要的一点就是他的失配指针,可以支持在一次匹配失败后自动跳转至下一个匹配位置从而避免从头重新匹配,降低复杂度。
  这玩意儿的复杂度是\(O(n)\)的。
  代码:

Code
template<int node_num,int set_size>
class AC_automation
{
	private:
		typedef char* str;
		int tot;
		int ch[node_size][set_size];
		int fail[node_size];
		int cnt[node_size];
	public:
		AC_automation(){tot=1;}
		void insert(str);
		void get_fail();
		int query(str);
}
template<int node_size,int set_size>
void AC_automation<node_size,set_size>::insert(str s)
{
	int p=1;
	int len=strlen(s);
	for(int i=0;i<len;i++)
	{
		int c=s[i]-'a'+1;
		if(!ch[p][c]) ch[p][c]=++tot;
		p=ch[p][c];
	}
	cnt[p]++;
}
template<int node_size,int set_size>
void AC_automation<node_size,set_size>::get_fail()
{
	queue<int> q;
	fail[1]=1;
	for(int i=1;i<=26;i++)
	{
		if(!ch[1][i]) ch[1][i]=1;
		else fail[ch[1][i]]=1,q.push(ch[1][i]);
	}
	while(!q.empty())
	{
		int x=q.front(),q.pop();
		for(int i=1;i<=26;i++)
		{
			if(ch[x][i]) fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
			else ch[x][i]=ch[fail[x]][i];
		}
	}
}
template<int node_size,int set_size>
int AC_automation<node_size,set_size>::query(str s)
{
	int p=1;
	int len=strlen(s);
	for(int i=0;i<len;i++)
	{
		int x=s[i]-'a'+1;
		p=ch[p][x];
		for(int j=p;j&&cnt[j];j=fail[j])
		{
			ans+=cnt[j];
			cnt[j]=0;
		}
	}
}

标签:AC,int,automation,str,fail,自动机,size
来源: https://www.cnblogs.com/Geek-Kay/p/15164810.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有