AC自动机总结

字典树

HDU - 1251 统计难题

 

模板:

const int N = 1000;//长度

//初始化 ac.insert();
//建立字典树 ac.insert();
//建立 fail,last指针 ac.build();
//输入文本串进行统计模式串 ac.query(s);
//统计出现次数 ac.getCount();


struct AC_Automata{
    int tire[N][4];
    int val[N];//结尾标记
    int last[N];//last指针
    int fail[N];//fail指针
    int count[N];//对应字符串 id 的出现次数统计
    int tot;

    void init(){
        tot = 1;
        val[0] = fail[0] = last[0]  =0;
        memset(tire[0],0,sizeof(tire[0]));
    }

    void insert(char *s,int v){
        int len = strlen(s);
        int root = 0;
        for(int i=0;i<len;i++){
            int id = get_id(s[i]);
            if(tire[root][id]==0){
                tire[root][id] = tot;
                memset(tire[tot],0,sizeof(tire[tot]));
                val[tot++] = 0;
            }
            root = tire[root][id];  
        }
        val[root] = 1;  
    }

    void build(){
        while(!q.empty()) q.pop();
        last[0] = fail[0] = 0;
        for(int i=0;i<4;i++){
            int root = tire[0][i];
            if(root!=0){
                fail[root] = 0;
                last[root] = 0;
                q.push(root);
            }
        }
        while(!q.empty()){
            int k = q.front();
            q.pop();
            for(int i=0;i<4;i++){
                int u = tire[k][i];
                if(u==0){
                    tire[k][i] = tire[fail[k]][i];
                    continue;
                }
                q.push(u);
                fail[u] =tire[fail[k]][i];
                last[u] = val[fail[u]]?fail[u]:last[fail[u]];
            }
        }
    } 
    void getCount(int i){
        if(val[i]){
            count[val[i]]++;
            get_count(last[i]);
        }
    }
    void query(char *s){
        int len = strlen(s);
        int j=0;
        for(int i=0;i<len;i++){
            int id = get_id(s[i]);
            while(j && tire[j][id]==0){
                j=fail[j];
            }
            j = tire[j][id];
            if(val[j])
                getCount(j);
            else if(last[j])
                getCount(j);
        }
    }
}ac;

 

posted @ 2019-08-12 17:27  Tianwell  阅读(158)  评论(0编辑  收藏  举报