AC自动机【模板】

模板

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stdlib.h>

using namespace std;
const int N=10000005;
int cnt;

char key[70];
char pattern[N];

struct Node{
	Node *next[26];
	Node *fail;
	int sum; 
};

Node *root;
void insert(char *s)
{
	Node *rt=root;
	for(int i=0;s[i];i++){
		int x=s[i]-'a';
		if(!rt->next[x]){
			Node *node=(struct Node*)malloc(sizeof(struct Node));
			for(int j=0;j<26;j++)
			  node->next[j]=NULL;
			node->fail=NULL;
			node->sum=0;
			rt->next[x]=node;
		}
		rt=rt->next[x];
	}
	rt->sum++;
}

void fail_pointer()
{
	queue<Node*>q;
	q.push(root);
	Node *p,*temp;
	while(!q.empty()){
		temp=q.front();
		q.pop();
		for(int i=0;i<26;i++){
			if(temp->next[i]){
				if(temp==root)
				  temp->next[i]->fail=root;
				else{
					p=temp->fail;
					while(p){
						if(p->next[i]){
							temp->next[i]->fail=p->next[i];
							break;
						}
						p=p->fail;
					}
					if(!p)
					  temp->next[i]->fail=root; 
				}
				q.push(temp->next[i]);
			}
		}
	}
}

void ac(char *s)
{
	Node *rt=root;
	for(int i=0;s[i];i++){
		int x=s[i]-'a';
		while(!rt->next[x]&&rt!=root)
		  rt=rt->fail;
		rt=rt->next[x];
		if(!rt)
		  rt=root;
		Node *temp=rt;
		while(temp!=root){
			if(temp->sum>=0){
				cnt+=temp->sum;
				temp->sum=-1;
			}
			else
			  break;
			temp=temp->fail;
		}
	}
}

int main()
{
	int T,n;
	scanf("%d",&T);
	while(T--){
		root=(struct Node*)malloc(sizeof(struct Node));
		for(int i=0;i<26;i++)
		  root->next[i]=NULL;
		root->fail=NULL;
		root->sum=0;
		scanf("%d",&n);
		getchar();
		for(int i=1;i<=n;i++){
			gets(key);
			insert(key);
		}
		gets(pattern);
		cnt=0;
		fail_pointer();
		ac(pattern);
		printf("%d\n",cnt);
	}
	return 0;
}


 

题目集锦

HDU2222 Keywords Search【AC自动机】

猜你喜欢

转载自blog.csdn.net/SongBai1997/article/details/82774499