1. 程式人生 > >AC自動機跟隨Kuangbing學習筆記

AC自動機跟隨Kuangbing學習筆記

//======================
// HDU 2222
// 求目標串中出現了幾個模式串
//輸入 
//1
//5
//she
//he
//say
//shr
//her
//yasherhs 
//====================
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;

struct Trie
{
	int next[500010][26],fail[500010],end[500010];
	int root,L;
	int newnode()
	{
		for(int i=0;i<26;i++)
			next[L][i]=-1;
		end[L++]=0;
		return L-1; 
	}
	void init()
	{
		L=0;
		root=newnode();
	} 
	void insert(char buf[])
	{
		int len = strlen(buf);
		int now = root;
		for(int i=0;i<len;i++)
		{
			if(next[now][buf[i]-'a']==-1)
			 	next[now][buf[i]-'a']=newnode();
			now=next[now][buf[i]-'a'];
		}
		end[now]++;
	}
	void build()
	{
		queue<int>Q;
		fail[root]=root;
		for(int i=0;i<26;i++)
			if(next[root][i]==-1)
				next[root][i]=root;						//匹配失效回到根節點繼續匹配 
			else  
			{
				fail[next[root][i]]=root;			    //第一層的失敗指標指向root 
				Q.push(next[root][i]);					//加入佇列    
			}
		while(!Q.empty())
		{
			int now=Q.front();
			Q.pop();
			for(int i=0;i<26;i++)
			{
				if(next[now][i]==-1)
					next[now][i]=next[fail[now]][i];
				else 
				{
					fail[next[now][i]]=next[fail[now]][i];
					Q.push(next[now][i]); 
				}
			}
		} 
	}
	int query(char buf[])
	{
		int len=strlen(buf);
		int now=root;
		int res=0;
		for(int i=0;i<len;i++)
		{ 
			now=next[now][buf[i]-'a'];
			int temp=now;
			while(temp!=root)
			{
				res+=end[temp];
				end[temp]=0;
				temp=fail[temp];
			} 
		} 
		return res;
	} 
	void debug()
	{
		for(int i=0;i<L;i++)
		{
			           printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
         			   for(int j = 0;j < 26;j++)
           			     printf("%2d",next[i][j]);
         			   printf("]\n");
		} 
	} 
};
char s[300];
char buff[1000005];
	Trie ac;
void input()
{
	int n;
	cin>>n;
	ac.init();
	for(int i=1;i<=n;i++)
	{
		scanf("%s",s);
		ac.insert(s);
	}
	ac.build();
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		input();
		scanf("%s",buff);
		printf("%d\n",ac.query(buff));
	}
}