【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; }