模板_AC自动机
2016-02-19 16:08
330 查看
简单粗暴的AK自动机模板+注释
训练指南的->
struct AhoCorasick{ struct Node{ Node *fail,*next[26];int cnt; Node(){for(int i=0;i<26;i++) next[i]=NULL;fail=NULL;cnt=0;} }*root; void insert(char *str){//建立Trie int l;l=strlen(str); Node *p=root; for(int i=0,tmp=str[i]-'a';i<l;p=p->next[tmp],tmp=str[++i]-'a') if(p->next[tmp]==NULL) p->next[tmp]=new Node();//没有该节点就新建一个 p->cnt++;//统计个数 } void build(){//bfs计算fail失配 queue<Node*> q;q.push(root);//队列 while(!q.empty()){ Node *p=q.front(),*tmp=NULL;q.pop();//弹出队首 for(int i=0;i<26;i++){ if(p->next[i]!=NULL){ if(p!=root){ for(tmp=p->fail;tmp!=NULL;tmp=tmp->fail){ if(tmp->next[i]!=NULL) {p->next[i]->fail=tmp->next[i];break;}//找到跳出循环 } if(tmp==NULL) p->next[i]->fail=root;//没有匹配的指向root } else p->next[i]->fail=root;//第一个字符 q.push(p->next[i]);//加入队列 } } } } int query(){//计算匹配个数 int l=strlen(str),res=0;Node *p=root; for(int i=0,ch=str[i]-'a';i<l;ch=str[++i]-'a'){ while(p->next[ch]==NULL&&p!=root) p=p->fail;//失配 p=p->next[ch];//查询字符 if(p==NULL) p=root;//重置 Node *tmp=p; while(tmp!=root&&tmp->cnt!=-1)//累计 res+=tmp->cnt,tmp->cnt=-1,tmp=tmp->fail; } return res; } void init(){root=new Node();}//初始化 }ac;
训练指南的->
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=500050,M=26; struct Trie { int ch [M]; int size,ans; int val ; int last ; int f ; int cnt ; inline int idx(char c) {return c-'a';} void init() { size=ans=0; memset(ch[0],0,sizeof(ch[0])); } void insert(char* T) { int n=strlen(T),u=0; for(int i=0;i<n;i++) { int d=idx(T[i]); if(!ch[u][d]) { ch[u][d]=++size; memset(ch[size],0,sizeof(ch[size])); val[size]=last[size]=f[size]=cnt[size]=0; } u=ch[u][d]; } cnt[u]++,val[u]=1; } void find(char* T) { int n=strlen(T),u=0; for(int i=0;i<n;i++) { int d=idx(T[i]); u=ch[u][d]; if(val[u]) print(u); else if(val[last[u]]) print(last[u]); } printf("%d\n",ans); } void print(int j) { if(j&&val[j]) ans+=cnt[j],val[j]=0,print(last[j]); } void get_f() { queue<int> q; for(int t=0;t<M;t++) if(ch[0][t]) q.push(ch[0][t]); while(!q.empty()) { int u=q.front();q.pop(); for(int t=0;t<M;t++) { if(!ch[u][t]) {ch[u][t]=ch[f[u]][t];continue;} int r=ch[u][t]; q.push(r); f[r]=ch[f[u]][t]; last[r]= val[f[r]]?f[r]:last[f[r]]; } } } }AC;
相关文章推荐
- 算法训练 字串统计
- Android ListView 中的Adapter 优化 缓存 getContext()
- 【BZOJ3594】【SCOI2014】 方伯伯的玉米田
- Ionic 环境配置
- Android APK签名介绍02
- node.js events模块提供的类:EventEmitter类
- xib父视图半透明 子视图正常
- MIME类型记录
- NoSQL和Redis简介及Redis在Windows下的安装和使用教程
- 另一种基于 WinCE 的 Silverlight 应用建立过程
- vc编译设置区别
- event.returnValue=false和return false的用处
- DateDemo 时间格式类 SimpleDateFormat DateFormat
- 手势冲突解决方案
- ssh 密钥模式免输密码
- jquery基础
- win7 启动后内存占用达到99% 解决方案
- poj seek the name,seek the fame
- redis和memcache
- 前端自动化测试探索