模板_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
原创粉丝点击