AC自动机
Posted water-radish
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机相关的知识,希望对你有一定的参考价值。
//AC自动机 //相当于在Trie树上求KMP //可以求一个字符串的多个匹配子串 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<queue> using namespace std; struct uio{ int son[27],end,fail;//fail指针相当于KMP中的next[]数组 }trie[1000001]; int n,cnt; char c[1000001]; void insert(char* a) { int now=0,len=strlen(a); for(int i=0;i<len;i++) { int c=int(a[i]-‘a‘); if(!trie[now].son[c]) trie[now].son[c]=++cnt; now=trie[now].son[c]; } trie[now].end+=1; } void get_fail()//求fail指针 { queue<int> que; while(!que.empty()) que.pop(); //将根节点的fail指针预处理出来 //原因是根节点的fail指针指向了根节点自身 //若在BFS中处理会导致其儿子也将fail指针指向儿子自身 for(int i=0;i<26;i++) if(trie[0].son[i]) { trie[trie[0].son[i]].fail=0; que.push(trie[0].son[i]); } while(!que.empty())//BFS { int now=que.front(); que.pop(); //在取出节点后,正确的操作应为: //循环26个字母,若不存在儿子则continue //否则查询:表示字母sth的儿子(下文称sth)的父亲(也就是刚从队列中取出的节点,下文称sth_fa), //其fail指针指向的节点(下文称sth2_fa)是否也有一个表示字母sth的儿子(下文称sth2) //若有则直接将sth的fail指针指向sth2 //否则查询sth2_fa的fail指针指向的节点是否也有一个表示字母sth的儿子 //重复以上过程直至找到一个符合条件的儿子或是回溯到root节点 //对于后者直接将sth的fail指针指向root即可 for(int i=0;i<26;i++) { if(trie[now].son[i]) { trie[trie[now].son[i]].fail=trie[trie[now].fail].son[i]; que.push(trie[now].son[i]); } else trie[now].son[i]=trie[trie[now].fail].son[i]; } //那么以上代码为什么正确呢 //考虑分3种情况 //1.有此儿子且第一次查询就找到应指向的节点 则直接指向即可 //2.有此儿子但第一次查询找到了一个空节点 则直接指向即可 //原因是在遇到空节点时会将它的fail指针指向 //其父亲的fail指针指向的节点的表示相同字母的儿子 //这就相当于做了本应在递归过程中进行的操作 //3.无此儿子 这种情况的操作不再赘述 } } void query(char* a) { int now=0,len=strlen(a); int ans=0; for(int i=0;i<len;i++) { now=trie[now].son[a[i]-‘a‘]; for(int j=now;j&&trie[j].end!=-1;j=trie[j].fail) //未回溯至根节点且未查询过 ans+=trie[j].end,trie[j].end=-1; } printf("%d ",ans); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%s",c),insert(c); trie[0].fail=0;//标志结束 get_fail(); scanf("%s",c); query(c); return 0; }
以上是关于AC自动机的主要内容,如果未能解决你的问题,请参考以下文章
HDU4057 Rescue the Rabbit(AC自动机+状压DP)
Codeforces 86C Genetic engineering(AC自动机+DP)
POJ1699 Best Sequence(AC自动机+状压DP)