zoukankan      html  css  js  c++  java
  • HDOJ 3065 病毒侵袭持续中(AC自动机入门)

    思路:

    AC自动机,单词统计。

    #include <iostream>
    #include <deque>
    using namespace std;
    
    const int MAX_NODE = 1000 * 50 + 10;
    const int CHILD_NUM = 26;
    
    char virus[1010][56];
    int num[1010];
    
    class AcAutomaton 
    {
    private:
        int size;
        int trie[MAX_NODE][CHILD_NUM];
        int value[MAX_NODE];
        int fail[MAX_NODE];
        int table[128];
    
    public:
        void Initialize()
        {
            fail[0] = 0;
            memset(table, -1, sizeof(table));
            for (int i = 0; i < 26; ++i)
                table['A' + i] = i;
        }
    
        void Reset()
        {
            size = 1;
            memset(trie[0], 0, sizeof(trie[0]));
            memset(fail, 0, sizeof(fail));
            memset(value, 0, sizeof(value));
        }
    
        void Insert(char* word, int key)
        {
            int p = 0;
            for (int i = 0; word[i]; ++i)
            {
                int m = table[word[i]];
                if (!trie[p][m])
                {
                    memset(trie[size], 0, sizeof(trie[0]));
                    trie[p][m] = size++;
                }
                p = trie[p][m];
            }
            value[p] = key;
        }
    
        void Construct()
        {
            deque<int> deq;
    
            for (int i = 0; i < CHILD_NUM; ++i)
                if (trie[0][i])
                {
                    fail[trie[0][i]] = 0;
                    deq.push_back(trie[0][i]);
                }
    
            while (!deq.empty())
            {
                int u = deq.front();
                deq.pop_front();
                for (int i = 0; i < CHILD_NUM; ++i)
                {
                    int& v = trie[u][i];
                    if (v)
                    {
                        fail[v] = trie[fail[u]][i];
                        deq.push_back(v);
                    }
                    else
                        v = trie[fail[u]][i];
                }
            }
        }
    
        void Work(char* word, int arr[])
        {
            int p = 0;
            for (int i = 0; word[i]; ++i)
            {
                int m = table[word[i]]; 
                if (m == -1) 
                {
                    p = 0; continue;
                }
                int t = p = trie[p][m];
                while (value[t])
                {
                    ++arr[value[t]];
                    t = fail[t];
                }
            }
        }
    };
    
    AcAutomaton Ac;
    char word[2000010];
    
    int main()
    {
        int n;
        Ac.Initialize();
        while (~scanf("%d", &n))
        {
            Ac.Reset();
    
            for (int i = 1; i <= n; ++i)
            {
                scanf("%s", virus[i]);
                Ac.Insert(virus[i], i);
            }
            Ac.Construct();
    
            scanf("%s", word);
            memset(num, 0, sizeof(num));
            Ac.Work(word, num);
    
            for (int i = 1; i <= n; ++i)
                if (num[i])
                    printf("%s: %d\n", virus[i], num[i]);
        }
        return 0;
    }
  • 相关阅读:
    每日一题_191118
    每日一题_191117
    每日一题_191116
    每日一题_191115
    每日一题_191114
    每日一题_191113
    每日一题_191112
    每日一题_191111
    每日一题_191110
    一道抛物线自编题的思考
  • 原文地址:https://www.cnblogs.com/kedebug/p/2880640.html
Copyright © 2011-2022 走看看