模板_AC自动机
来源:互联网 发布:淘宝网包包新款 编辑:程序博客网 时间:2024/05/29 07:39
简单粗暴的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[N][M]; int size,ans; int val[N]; int last[N]; int f[N]; int cnt[N]; 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;
1 0
- 模板_AC自动机
- 模板_AC自动机
- HDU2222_Keywords Search _AC自动机模板题
- 【字符串_AC自动机专辑】
- 踹图_AC自动机
- Vision_字符串_AC自动机
- hdu 2896 病毒侵袭_ac自动机
- 【AC自动机】AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- 后缀自动机 模板
- AC自动机模板 hdu2222
- hdu4622 后缀自动机 模板
- AC自动机模板
- C语言 基础练习题
- dblink名字后面有字符串REGRESS.RDBMS.DEV.US.ORACLE.COM
- Android ListView 中的Adapter 优化 缓存 getContext()
- 【BZOJ3594】【SCOI2014】 方伯伯的玉米田
- Android APK签名介绍02
- 模板_AC自动机
- Android5.0+(CollapsingToolbarLayout)
- node.js events模块提供的类:EventEmitter类
- Guava学习笔记:Google Guava 类库简介
- 如何将错误日志传到服务器。
- startActivityForResult和setResult详解
- SpringMVC 用 ModelAndview 传递参数的问题
- Unity dll 热更新 基础框架
- 查找和节点相连接的节点