AC自动机(模板)

\(\color{Purple}{只是照着敲了一遍,下次再来看吧~}\)

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+9;
struct Tire{
	int fail,zi[26],end;
}AC[maxn];int tot;
void insert(string s)
{
	int len=s.length(),now=0;
	for(int i=0;i<len;i++)
	{
		int ch=s[i]-'a';
		if(!AC[now].zi[ch])	AC[now].zi[ch]=++tot;
		now=AC[now].zi[ch];
	}
	AC[now].end+=1;
}
void make_fail()
{
	queue<int>q;
	for(int i=0;i<=25;i++)
	if(AC[0].zi[i]!=0)
	{
		AC[AC[0].zi[i]].fail=0;//指向根节点
		q.push(AC[0].zi[i]); 
	}
	while(!q.empty())
	{
		int u=q.front();q.pop();
		for(int i=0;i<=25;i++)
		{
			if(AC[u].zi[i]!=0)
			{
				AC[AC[u].zi[i]].fail=AC[AC[u].fail].zi[i];
				//子节点的fail指针指向父亲fail指针指向的节点的相同子节点
				q.push(AC[u].zi[i]); 
			}
			else	AC[u].zi[i]=AC[AC[u].fail].zi[i]; 
			//没有子节点,创造子节点指向当前节点fail指针的节点 
		}
	}
}
int AC_automation(string s)//开始AC辣~ 
{
	int len=s.length(),now=0,ans=0;
	for(int i=0;i<len;i++)
	{
		now=AC[now].zi[s[i]-'a'];//向下一层冲!
		for(int j=now;j&&AC[j].end!=-1;j=AC[j].fail)
		{
			ans+=AC[j].end;
			AC[j].end=-1;
		}
	}
	return ans;
}
int main()
{
	int n;string s;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>s;
		insert(s);
	}
	AC[0].fail=0;//结束标志
	make_fail();
	cin>>s;//模式串读入
	cout<<AC_automation(s);
	return 0;//谢幕! 
}

猜你喜欢

转载自www.cnblogs.com/iss-ue/p/12770470.html