【算法练习】HDU 2222 Keywords Search (AC自动机)

题解

AC自动机

代码

#include <bits/stdc++.h>
using namespace std;
const int nmax = 1e6 + 7;
const int sigma = 26;

struct Aho {
    int sz;
    queue<int> que;
    struct Node {
        int nxt[sigma];
        int cnt, fail;
    } node[nmax];

    void init() {
        while(!que.empty()) que.pop();
        memset(node, 0, sizeof node);
        sz = 1;
    }

    inline int idx(const char & ch) {return ch - 'a';}

    void insert(char * S) {
        int len = strlen(S);
        int now = 0;
        for(int i = 0; i < len; ++i) {
            char ch = S[i];
            if(!node[now].nxt[idx(ch)])
                node[now].nxt[idx(ch)] = sz++;
            now = node[now].nxt[idx(ch)];
        }
        node[now].cnt ++;
    }

    void build_fail() {
        node[0].fail = -1;
        que.push(0);
        while(!que.empty()) {
            int u = que.front(); que.pop();
            for(int i = 0; i < sigma; ++i) {
                if(node[u].nxt[i]) {
                    if(u == 0) node[node[u].nxt[i]].fail = 0;
                    else {
                        int v = node[u].fail;
                        while(v != -1) {
                            if(node[v].nxt[i]) {
                                node[node[u].nxt[i]].fail = node[v].nxt[i];
                                break;
                            }
                            v = node[v].fail;
                        }
                        if(v == -1) node[node[u].nxt[i]].fail = 0;
                    }
                    que.push(node[u].nxt[i]);
                }
            }
        }
    }

    int Get(int u) {
        int ans = 0;
        while(u) {
            ans += node[u].cnt;
            node[u].cnt = 0;
            u = node[u].fail;
        }
        return ans;
    }

    int match(char * S) {
        int len = strlen(S);
        int ans = 0, now = 0;
        for(int i = 0; i < len; ++i) {
            char ch = S[i];
            if(node[now].nxt[idx(ch)])
                now = node[now].nxt[idx(ch)];
            else {
                int fa = node[now].fail;
                while(fa != -1 && !node[fa].nxt[idx(ch)]) fa = node[fa].fail;
                if(fa == -1) now = 0;
                else now = node[fa].nxt[idx(ch)];
            }
            if(node[now].cnt)
                ans += Get(now);
        }
        return ans;
    }
} aho;
int t,n;
char str[nmax];
int main() {
    scanf("%d", &t);
    while(t--) {
        aho.init();
        scanf("%d", &n);
        for(int i = 0; i < n; ++i) {
            scanf("%s", str);
            aho.insert(str);
        }
        aho.build_fail();
        scanf("%s",str);
        printf("%d\n", aho.match(str));
    }
}

猜你喜欢

转载自blog.csdn.net/pengwill97/article/details/81537467