zoukankan      html  css  js  c++  java
  • AC自动机 HDOJ 2222 Keywords Search

    题目链接

    题意:每个文本串的出现次数

    分析:入门题,注意重复的关键字算不同的关键字,还有之前加过的清零。   新模板,加上last跑快一倍

    #include <bits/stdc++.h>
    
    struct AC {
        static const int NODE = 10000 * 50 + 5;
        static const int SIZE = 26;
        int ch[NODE][SIZE], fail[NODE], last[NODE];
        int end[NODE];
        int sz;
        
        void clear() {
            memset (ch[0], 0, sizeof (ch[0]));
            end[0] = 0;
            sz = 1;
        }
        int idx(char ch) {
            return ch - 'a';
        }
        void insert(char *str) {
            int u = 0;
            for (int c, i=0; str[i]; ++i) {
                c = idx (str[i]);
                if (!ch[u][c]) {
                    memset (ch[sz], 0, sizeof (ch[sz]));
                    end[sz] = 0;
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            end[u]++;
        }
        void build() {
            fail[0] = 0;
            std::queue<int> que;
            for (int c=0; c<SIZE; ++c) {
                int u = ch[0][c];
                if (u) {
                    fail[u] = 0;
                    last[u] = 0;
                    que.push (u);
                }
            }
            while (!que.empty ()) {
                int r = que.front (); que.pop ();
                for (int c=0; c<SIZE; ++c) {
                    int u = ch[r][c];
                    if (!u) {
                        ch[r][c] = ch[fail[r]][c];
                    } else {
                        fail[u] = ch[fail[r]][c];
                        last[u] = end[fail[u]] ? fail[u] : last[fail[u]];
                        que.push (u);
                    }
                }
            }
        }
        int query(char *text) {
            int ret = 0, u = 0;
            for (int c, i=0; text[i]; ++i) {
                c = idx (text[i]);
                u = ch[u][c];
                int t = u;
                while (t) {
                    ret += end[t];
                    end[t] = 0;
                    t = last[t];
                }
            }
            return ret;
        }
    };
    AC ac;
    char p[55], t[1000010];
    
    int main(void)    {     //HDOJ 2222 Keywords Search
        int T;  scanf ("%d", &T);
        while (T--) {
            int n;   scanf ("%d", &n);
            ac.clear ();
            for (int i=1; i<=n; ++i)    {
                scanf ("%s", p);    ac.insert (p);
            }
            ac.build ();    scanf ("%s", t);
            printf ("%d
    ", ac.query (t));
        }
    
        return 0;
    }
    编译人生,运行世界!
  • 相关阅读:
    C语言---堆的实现
    python的matplotlib---雷达图
    python的matplotlib饼状图
    python的matplotlib折线图
    python的matplotlib散点图学习
    python的matplotlib散点图
    C语言---队列(链表实现)
    hadoop集群启动与关闭需要输入密码
    hadoop集群启动时需要输入密码
    C语言---堆栈(链表实现)
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4737729.html
Copyright © 2011-2022 走看看