zoukankan      html  css  js  c++  java
  • 【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;
        
    }
  • 相关阅读:
    等待事件统计信息--Wait Events Statistics
    实时监控SQL
    PHP中常用的魔术方法
    PHP生成缩略图(3)--封装类
    PHP生成缩略图(2)--等比缩略图
    PHP生成缩略图(1)--简单缩略图
    调用天气预报接口
    使用JSON实现分页
    使用AJAX实现分页
    AJAX缓存问题
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196440.html
Copyright © 2011-2022 走看看