AC 自动机(模板)
2017-04-16 11:24
302 查看
AC自动机 就是一个多子串匹配的东西,哪有那么厉害,和kmp一样有一个fail指针(下面代码打错了。。,不改了),匹配失败了就跳到file指针,因为fail指针都是从父节点的fail指针推过来的,这样就可以保证前面是一样的了。
AC自动机分三步,第一步是建trie树,第二步是建fail指针(最关键的一步,否则就和字典树一样了),第三步是匹配。
1.建trie图
代码在这
![](https://img-blog.csdn.net/20170416112415644?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzY3OTk5NDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
很容易就建完了。
2.建fail指针
![](https://img-blog.csdn.net/20170416112309669?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzY3OTk5NDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
相对较难理解的
有三个变量(都是编号,不是字符)
1 父节点(就是出队的)
2 子节点(就是父结点的子节点)
3 file指向的节点(就是父节点的fail指针,下面简称1,2,3)
其实就是用队列实现的,先把根节点的子节点入队,在一个个出队,如果3.next[2]有值,出队时将2的fail指针连向3的next[2],没有就把继续找3的fail,直到fail.next[2]有值,或到了根节点。
3.匹配
有一个变量表示当前字符
这样AC自动机就完成了
丑陋的代码在这
AC自动机分三步,第一步是建trie树,第二步是建fail指针(最关键的一步,否则就和字典树一样了),第三步是匹配。
1.建trie图
代码在这
很容易就建完了。
2.建fail指针
相对较难理解的
有三个变量(都是编号,不是字符)
1 父节点(就是出队的)
2 子节点(就是父结点的子节点)
3 file指向的节点(就是父节点的fail指针,下面简称1,2,3)
其实就是用队列实现的,先把根节点的子节点入队,在一个个出队,如果3.next[2]有值,出队时将2的fail指针连向3的next[2],没有就把继续找3的fail,直到fail.next[2]有值,或到了根节点。
3.匹配
有一个变量表示当前字符
遵循两种情况 1.原串字符和当前指针匹配,就继续向下去匹配吧 2.不匹配,就把当前指针移到当前指针的fail指针上,再继续匹配,直到根节点。
这样AC自动机就完成了
丑陋的代码在这
#include<cstdio> #include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #define id(x) x-'a'; using namespace std; struct st{ int nex[26]; int file; int count; int innn(){ memset(nex, -1, sizeof(nex)); count=0; file=0; } }s[9999]; int cnt; int ins(char ss[]){ int p=0; for(int i=0;i<strlen(ss);i++){ int x=id(ss[i]); < 4000 span class="hljs-keyword">if(s[p].nex[x]==-1) { s[cnt].innn(); s[p].nex[x]=cnt++; } p=s[p].nex[x]; } s[p].count++; } int d[999999]; int make_file(){ int tail=0,head=0; for(int i=0;i<=25;i++) { if(s[0].nex[i]!=-1){ d[tail++]=s[0].nex[i]; } } while(head!=tail){ int x=d[head];head++; for(int i=0;i<=25;i++){ if(s[x].nex[i]!=-1){ d[tail++]=s[x].nex[i]; int tmp=s[x].file; while(s[tmp].nex[i]==-1&&tmp>0){ tmp=s[tmp].file; } if(s[tmp].nex[i]!=-1){ tmp=s[tmp].nex[i]; } s[s[x].nex[i]].file=tmp; } } } } int tot;char sr[9999]; char sh[999]; int n; int pipei(){ int p=0; for(int i=0;i<strlen(sr);i++) { int x=id(sr[i]); while(p>0&&s[p].nex[x]==-1){ p=s[p].file; } if(s[p].nex[x]!=-1){ p=s[p].nex[x]; // tot+=s[p].count; // s[p].count=0; int ind=p; while(ind > 0 && s[ind].count != -1) { tot += s[ind].count; s[ind].count = -1; ind = s[ind].file; } } } printf("%d",tot); return 0; } int main(){ gets(sr); s[0].innn();cnt=1; scanf("%d\n",&n); while(n--){ scanf("%s",sh); //printf("%s\n",sh); ins(sh); } make_file(); pipei(); }
相关文章推荐
- 模板_AC自动机
- HDU 2222 Keywords Search(AC自动机模板题)
- hdu 3065 病毒侵袭持续中(ac自动机模板题)
- 【COCI2012 Task 5】T6 poplocavanje ([JZOJ3172]贴瓷砖)(AC自动机模板)
- hdu 2222 Keywords Search(AC自动机模板题)
- hdu:2222:Keywords Search(AC自动机模板题)
- (AC自动机)模板
- 【HDU】病毒侵袭(AC自动机模板题)
- HDU 2896 (AC自动机模板题)
- AC自动机模板 LA4670 Dominating Patterns 出现次数最多的字串 BNUOJ11552 UVA1449
- HDU 2222 (AC自动机模板题)
- 邝斌的ACM模板(AC 自动机)
- HDU - 2222 Keywords Search(AC自动机模板题)
- 【模板】AC自动机(加强版) 洛谷3796 AC自动机
- 【模板】AC自动机
- HDU 2222 Keywords Search (AC自动机模板题)
- hdu 2896(AC自动机模板题)
- HDU 2222 Keywords Search(AC自动机模板题)
- hdu 5384 Danganronpa(AC自动机模板题)
- AC自动机模板 LA4670