您的位置:首页 > 其它

模板_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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: