【hdu 2222】Keywords Search

【题目链接】

       点击打开链接

【算法】

      此题是AC自动机模板题

      AC自动机是很神奇的算法,简单点来说,就是在一棵字典树上进行KMP,它的应用范围很广,非常实用

      这篇博客写得很好,推荐阅读 :

      http://blog.csdn.net/creatorx/article/details/71100840

【代码】

        个人觉得我的代码还是写得不错的,大家可以尝试阅读一下,应该可读性较高.

#include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <stack>
#include <limits.h>
using namespace std;

int T,N,i;
char pattern[1000010],s[10010][60];

template <typename T> inline void read(T &x) {
    int f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
    for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
}

template <typename T> inline void write(T x) {
    if (x < 0) { putchar('-'); x = -x; }
    if (x > 9) write(x/10);
    putchar(x%10+'0');    
}

template <typename T> inline void writeln(T x) {
    write(x);
    puts("");    
}

struct AC_Automation {
    int tot;
    struct node {
        int next[26];
        int fail;
        int sum;
    } trie[5000010];
    void clear() {
        int i;
        for (i = 0; i <= tot; i++) {
            trie[i].sum = trie[i].fail = 0;
            memset(trie[i].next,0,sizeof(trie[i].next));
        }
        tot = 0;
    }    
    void insert(char *s) {
        int i,len,root=0,x;
        len = strlen(s);
        for (i = 0; i < len; i++) {
            x = s[i] - 'a';
            if (!trie[root].next[x]) trie[root].next[x] = ++tot;
            root = trie[root].next[x]; 
        }
        ++trie[root].sum;
    }
    void rebuild() {
        int i,root,tmp;
        queue<int> q;
        q.push(0);
        trie[0].fail = -1;
        while (!q.empty()) {
            root = q.front(); q.pop();
            for (i = 0; i < 26; i++) {
                if (trie[root].next[i]) {
                    if (!root)
                        trie[trie[root].next[i]].fail = 0;    
                    else {
                        tmp = trie[root].fail;
                        while (tmp != -1) {
                            if (trie[tmp].next[i]) {
                                trie[trie[root].next[i]].fail = trie[tmp].next[i];
                                break;
                            }
                            tmp = trie[tmp].fail;
                        }
                        if (tmp == -1) trie[trie[root].next[i]].fail = 0;
                    }
                    q.push(trie[root].next[i]);
                }
            }
        }
    }
    void query(char *s) {
        int i,x,len,tmp,p=0,ans=0;
        len = strlen(s);
        for (i = 0; i < len; i++) {
            x = s[i] - 'a';
            while ((p != 0) && (!trie[p].next[x])) p = trie[p].fail;
            p = trie[p].next[x];
            tmp = p;
            while (tmp) {
                if (trie[tmp].sum != 0) {
                    ans += trie[tmp].sum;
                    trie[tmp].sum = 0; 
                } else break;
                tmp = trie[tmp].fail;
            }
        }
        writeln(ans);
    }
} ACAM;
 
int main() {
    
    read(T);
    while (T--) {
        read(N);
        for (i = 1; i <= N; i++) gets(s[i]);
        gets(pattern);
        ACAM.clear();
        for (i = 1; i <= N; i++) ACAM.insert(s[i]);
        ACAM.rebuild();
        ACAM.query(pattern);
    }
    
    return 0;
    
}
原文地址:https://www.cnblogs.com/evenbao/p/9196440.html