【HDU 2222】Keywords Search

  http://acm.hdu.edu.cn/showproblem.php?pid=2222

  今天学习了一下Aho-Corasick Automation。以前学了trie之后就停止搞字符串这方面了,因为今年NOI出现了AC自动机,所以要学习一下。

  这个题目的代码很多,我只是贴出来纪念一下第一道AC自动机,我也是跟别人学的。希望做的题多了,我也可以形成自己的风格(这个风格就比较符合我了)……


  加油!

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <queue>

using namespace std;



int n,Cases;

char pattern[51],match[1000001];

struct Aho_Corasick{

	struct NODE{

		int cnt;

		NODE *fail,*next[26];

		NODE(){fail=NULL,cnt=0;memset(next,0,sizeof(next));}

	}*root,*p;

	queue<NODE*> q;

	

	void init(){root=new NODE();}

	

	void build(){

		q.push(root);

		while(!q.empty()){

			NODE *cur=q.front();q.pop();

			for(int i=0;i<26;i++) 

				if(cur->next[i]){

					for(p=cur->fail;p;p=p->fail)

						if(p->next[i]){

							cur->next[i]->fail=p->next[i];

							break;

						}

					if(!p) cur->next[i]->fail=root;

					q.push(cur->next[i]);

				}

		}

	}

	

	void insert(char *s){

		int len=strlen(s);p=root;

		for(int i=0;i<len;i++){

			if(!p->next[s[i]-'a']) p->next[s[i]-'a']=new NODE();

			p=p->next[s[i]-'a'];

		}

		p->cnt++;

	}

	

	void query(char *s){

		int ans=0,len=strlen(s);p=root;

		for(int i=0;i<len;i++){

			while(!p->next[s[i]-'a'] && p!=root) p=p->fail;

			p=p->next[s[i]-'a'];

			if(!p) p=root;

			for(NODE *j=p;j&&j->cnt!=-1;j=j->fail)

				ans+=j->cnt,j->cnt=-1;

		}

		printf("%d\n",ans);

	}

}AC;



int main(){

	scanf("%d",&Cases);

	while(Cases--){

		scanf("%d",&n);

		AC.init();

		while(n--){

			scanf("%s",pattern);

			AC.insert(pattern);

		}

		AC.build();

		scanf("%s",match);

		AC.query(match);

	}

	return 0;

}

你可能感兴趣的:(search)