AC自动机(转载)

ac自动机学习博客 

本来以为是很高级的算法 其实理解以后并不难 只是在字典树的基础上用fail数组标记一下回朔的位置 加速查找 就可以实现多模式串的匹配查找

模版如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define ll long long int
using namespace std;
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1};
int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1};
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;
struct Trie{
    int trie[500007][26],fail[500007],cntword[500007];
    int sz,root;
    int newnode(){
        for(int i=0;i<26;i++)
            trie[sz][i]=-1;
        cntword[sz++]=0;
        return sz-1;
    }
    void init(){ //初始化 
        sz=0;
        root=newnode();
    }
    void insert(string s){ // 构建字典树 
        int len=s.length();
        int now=root;
        for(int i=0;i<len;i++){
            if(trie[now][s[i]-'a']==-1)
                trie[now][s[i]-'a']=newnode();
            now=trie[now][s[i]-'a'];
        }
        cntword[now]++;
    }
    void build(){ //构建fail数组 
        queue<int> q;
        fail[root]=root;
        for(int i=0;i<26;i++){
            if(trie[root][i]==-1)
                trie[root][i]=root;
            else{
                fail[trie[root][i]]=root;
                q.push(trie[root][i]);
            }
        }
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(trie[now][i]==-1)
                    trie[now][i]=trie[fail[now]][i];
                else{
                    fail[trie[now][i]]=trie[fail[now]][i];
                    q.push(trie[now][i]);
                }
            }
        }
    }
    int query(string s){ //查询操作 
        int len=s.length();
        int now=root;
        int res=0;
        for(int i=0;i<len;i++){
            now=trie[now][s[i]-'a'];
            int temp=now;
            while(temp!=root){
                res+=cntword[temp];
                cntword[temp]=0;
                temp=fail[temp];
            }
        }
        return res;
    }
};
Trie ac;
string s;
string ans;
int main(){
    ios::sync_with_stdio(false);return 0;
}

 

posted @ 2019-05-07 21:13  WAKBGAN  阅读(130)  评论(0编辑  收藏  举报