hdu2222 Keywords Search(AC自动机)

Keywords Search

#include <bits/stdc++.h>
using namespace std;
struct Tree
{
	Tree *next[26];
	Tree *fail;
	int count;
	Tree(){
		for(int i=0;i<26;++i){
			next[i]=NULL;
		}
		fail=NULL;
		count=0;
	}
};
char target[1000000];
void insert(Tree *p,char words[])
{
	int i=0;
	while(words[i]){
		int k=words[i++]-'a';
		if(p->next[k]==NULL)
			p->next[k]=new Tree();
		p=p->next[k];
	}
	p->count++;
}
void buildAC(Tree *r)
{
	queue<Tree*> q;
	q.push(r);
	while(!q.empty()){
		Tree *s=q.front();
		q.pop();
		for(int i=0;i<26;++i){
			if(s->next[i]){
				if(s==r) s->next[i]->fail=r;//s为根节点,则将后代next的fail指向r
				else{
					Tree *p=s->fail;
					while(p){
						if(p->next[i]){//有相同的后缀边
							s->next[i]->fail=p->next[i];
							break;
						}
						p=p->fail;
					}
					if(!p) s->next[i]->fail=r;//没有相同后缀边,失效时指向r
				}
				q.push(s->next[i]);
			}
		}
	}
}
int search(Tree *r)
{
	int i=0,cut=0;
	Tree *p=r;
	while(target[i]){
		int k=target[i++]-'a';
		while(!p->next[k]&&p!=r) p=p->fail;//跳转到失效指针
		p=p->next[k];
		if(p==NULL) p=r;
		Tree *t=p;
		while(t!=r&&t->count!=-1){
			cut+=t->count;
			t->count=-1;
			t=t->fail;
		}
	}
	return cut;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--){
		Tree r;
		int n;
		scanf("%d",&n);
		while(n--){
			char words[64];
			scanf("%s",words);
			insert(&r,words);
		}
		buildAC(&r);
		scanf("%s",target);
		printf("%d\n",search(&r));
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/gl486546/article/details/79834684