AC 自动机(模板)
来源:互联网 发布:php代码加密 编辑:程序博客网 时间:2024/05/22 01:09
AC自动机 就是一个多子串匹配的东西,哪有那么厉害,和kmp一样有一个fail指针(下面代码打错了。。,不改了),匹配失败了就跳到file指针,因为fail指针都是从父节点的fail指针推过来的,这样就可以保证前面是一样的了。
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]); 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();}
1 0
- AC 自动机(模板)
- (AC自动机)模板
- hdu2896(AC自动机模板)
- AC自动机模板(hdu2222)
- ac自动机模板(hdu2222)
- ac自动机模板(hdu2222)
- AC自动机模板(【CJOJ1435】)
- 【AC自动机】AC自动机模板
- ac自动机(dp)<AC自动机模板> ---高精度处理
- 字符串模板总结(一):AC自动机
- AC自动机模板(数组+指针)hdu2222
- AC自动机(模板题)hdu2896
- 数单词 (AC自动机模板题)
- AC自动机模板(数组实现版)
- 病毒侵袭(ac自动机模板)
- HDU-5384Danganronpa(AC自动机模板)
- AC自动机入门+模板 (HDU 2222)
- HDU 2222 (AC自动机模板)
- 02-线性结构3 Reversing Linked List (25分)
- 欢迎使用CSDN-markdown编辑器
- 判断一个串包含的字符串是否在另外个串中出现。
- js中arguments理解
- 九度oj 题目1007:奥运排序问题(但无法通过)
- AC 自动机(模板)
- P3389 【模板】高斯消元法
- RandomAccessFile 类
- Spark入门
- Linux---find命令及使用
- BigDecimal 小数点处理
- 100005. Shoes
- 多线程基础部分之生产消费者案例
- Guice