HDU 2222 Keywords Search (AC自动机模板题)

题目链接:HDU 2222


终于看明白AC自动机了,自己敲的模板,1A。

首先在Trie树上”挂“上所有的单词

然后在树上构造fail指针。

Trie树上每一个字母的fail指针要么指向父节点,要么指向root,如果其父节点上有相同的字母,指向父节点对应的字母,否则指向root;

可以看出需要一层一层的构建,所以需要用到队列BFS。

查询操作,如果顺着字典树找没有这个字母,就通过fail指针去找,直到找到或者找到root。

如果找到,并且字母为单词结尾,则cnt++,然后通过fail指针继续匹配看是否仍有可以匹配的单词。

源代码

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct node{
	node *next[26];
	int count ; //记录
	node* fail;
	node(){
		count = 0;
		fail = NULL;
		memset(next,0,sizeof(next));
	}
}*q[5000000];
int head,tail;
char str[1000010];
node *root;
void insert(char *s){ //构建trie
	int len = strlen(s);
	node *p = root;
	for(int i=0;i<len;i++){
		int index = s[i]-'a';
		if(!p->next[index])
			p->next[index] = new node;
		p=p->next[index];
	}
	p->count++;
}
void build_ac_automation(){ //初始化fail指针
	q[tail++] = root;
	while(head<tail){
		node *p = q[head++];
		node *tmp = NULL;
		for(int i=0;i<26;i++){
			if(p->next[i] != NULL){
				if(p == root)//首元素必须指根
					p->next[i]->fail = root;
				else{
					tmp =  p->fail; //失败指针(跳转指针)
					while(tmp != NULL){
						if(tmp->next[i] != NULL){//找到匹配
							p->next[i]->fail = tmp->next[i];
							break;
						} //如果没找到,则继续向上一个失败指针找
						tmp = tmp->fail;
					}
					if(tmp == NULL) //为空 则从头匹配
						p->next[i]->fail = root;
				}
				q[tail++] = p->next[i];//下一层入队
			}
		}
	}
}
int query(){
	int len = strlen(str);
	node *p = root;
	int cnt = 0;
	for(int i=0;i<len;i++){
		int index = str[i]-'a';
		while(p->next[index] == NULL && p!=root)
			p = p->fail;
		p = p->next[index];
		if(p == NULL)
			p = root;
		node *tmp = p;//tmp 动 , p不动。
		while(tmp != root && tmp->count != -1){
			cnt += tmp->count;
			tmp->count = -1;
			tmp = tmp ->fail; 
		}
	}
	return cnt;
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		 head= tail = 0;
		root = new node;
		int n;
		scanf("%d",&n);
		char s[10010];
		for(int i=0;i<n;i++){
			scanf("%s",s);
			insert(s);
		} 
		build_ac_automation();
		scanf("%s",str);
		int ans = query();
		printf("%d\n",ans);
	}
	return 0;
}


posted @ 2015-10-27 22:21  编程菌  阅读(172)  评论(0编辑  收藏  举报