zoukankan      html  css  js  c++  java
  • HDU 2222 AC自动机

    AC自动机模板题。

    什么是Fai指针,指向出现了的最长后缀。

    怎么统计,匹配到了模式串,但是,是仅仅一个当前的节点数吗? 

    不是的,还要继续往Fail指针上走,统计所有的cnt之和。

    这个题目设计到,每个模式串只能用一次,在Fail树中,统计过的,要归0;

    自动机第一次理解,谢谢卿学姐的视频资料。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    #define MAX_N 1000005
    #define MAX_Tot 500005
    
    
    struct  Aho {
        struct state {
            int next[26];
            int fail,cnt;
        }stateTable[MAX_Tot];
    
        int size;
        std::queue<int> que;
    
        void init() {
            while(que.size()) que.pop();
            for(int i=0; i < MAX_Tot; i++) {
                memset(stateTable[i].next,0,sizeof(stateTable[i].next));
                stateTable[i].fail = stateTable[i].cnt = 0;
            }
            size = 1;
        }
    
        void insert(char * S) {
            int n = strlen(S);
            int now = 0;
            for(int i=0; i < n; i++) {
                char c = S[i];
                if(!stateTable[now].next[c - 'a'])
                    stateTable[now].next[c - 'a'] = size ++;
                now = stateTable[now].next[c - 'a'];
            }
            stateTable[now].cnt++;
        }
    
        void build() {
            stateTable[0].fail = -1;
            que.push(0);
    
            while(que.size()) {
                int u = que.front();
                que.pop();
    
                for(int i=0; i < 26; i++) {
                    if(stateTable[u].next[i]) {
                        if(u==0) stateTable[stateTable[u].next[i]].fail = 0;
                        else {
                            int v = stateTable[u].fail;
                            while(v!=-1) {
                                if(stateTable[v].next[i]) {
                                    stateTable[stateTable[u].next[i]].fail = stateTable[v].next[i];
                                    break;
                                }
                                v = stateTable[v].fail;
                            }
                            if(v==-1)
                                stateTable[stateTable[u].next[i]].fail = 0;
                        }
                        que.push(stateTable[u].next[i]);
                    }
                }
            }
        }
    
        int Get(int u) {
            int res = 0;
            while(u) {
                res = res + stateTable[u].cnt;
                stateTable[u].cnt = 0;
                u = stateTable[u].fail;
            }
            return res;
        }
    
        int match(char *S) {
            int n = strlen(S);
            int res = 0,now = 0;
            for(int i=0; i < n; i++) {
                char c = S[i];
                if(stateTable[now].next[c - 'a'])
                    now = stateTable[now].next[c - 'a'];
                else {
                    int p = stateTable[now].fail;
                    while(p!=-1&&stateTable[p].next[c - 'a']==0)
                        p = stateTable[p].fail;
                    if(p==-1) now = 0;
                    else now = stateTable[p].next[c - 'a'];
                }
    
                if(stateTable[now].cnt)
                    res = res + Get(now);
    
            }
            return res;
        }
    
    }aho;
    
    int T;
    int N;
    char S[1000005];
    
    int main() {
        scanf("%d",&T);
    
        while(T--) {
    
            scanf("%d",&N);
            aho.init();
            for(int i=0; i < N; i++) {
                scanf("%s",S);
                aho.insert(S);
            }
    
            aho.build();
    
            scanf("%s",S);
            printf("%d
    ", aho.match(S));
    
        }
        return 0;
    }
  • 相关阅读:
    ADSL自动更换IP的方法
    css框架 一个可控性强的css+xhtml页面布局生成器。
    Linux环境配置之LAMP搭建(源码安装)
    PHP小技巧
    Google首页电吉他源代码下载
    Jquery 插件可以用来操作定界窗,将在定界窗内选取的项目放到父窗口内
    今天見鬼了
    今天闲着没事去公园玩了一下,随手拍了几张
    PHP利用PHPMailer组件的Gmail发信能力发送电子邮件
    端午节放假去台湾中部山区野餐时照的
  • 原文地址:https://www.cnblogs.com/TreeDream/p/7388726.html
Copyright © 2011-2022 走看看