Cod sursa(job #1783957)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 19 octombrie 2016 17:14:57
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <bits/stdc++.h>

using namespace std;

class Trie
{
    public:

    Trie *son[26], *up;
    vector<int> q;
    vector<Trie*> down;
    int cnt;

    Trie()
    {
        cnt = 0;
        for(int i=0; i<26; ++i)
            this->son[i] = NULL;
        up = NULL;
        q.clear();
        down.clear();
    }

    void update(char *word, int ind)
    {
        if(word[0]==NULL)
        {
            this->q.push_back(ind);
            return;
        }

        int nxt = word[0] - 'a';

        if(this->son[nxt] == NULL)
            this->son[nxt] = new Trie();

        this->son[nxt]->update(word+1, ind);
    }
};

Trie *T = new Trie(), *k;
int n, i, ans[105], N, nxt;
char word[10005], A[1000005];

void BFS(Trie *root)
{
    queue<Trie*> Q;
    Trie *act, *k;
    int i;

    Q.push(root);

    while(Q.size())
    {
        act = Q.front();
        Q.pop();

        for(i=0; i<26; ++i)
        if(act->son[i] != NULL)
        {
            k = act->up;
            while(k!=NULL && k->son[i]==NULL)
                k = k->up;

            if(k==NULL) k = root;
            else k = k->son[i];

            act->son[i]->up = k;
            k->down.push_back(act->son[i]);

            Q.push(act->son[i]);
        }
    }
}

void get_result(Trie *root)
{
    for(auto it : root->down)
    {
        get_result(it);
        root->cnt += it->cnt;
    }

    for(auto it : root->q)
        ans[it] = root->cnt;
}

int main()
{
    ifstream zin("ahocorasick.in");
    ofstream zout("ahocorasick.out");

    zin>>A>>n;

    for(i=1; i<=n; ++i)
    {
        zin>>word;
        T -> update(word, i);
    }

    BFS(T);

    k = T;
    N = strlen(A);
    for(i=0; i<N; ++i)
    {
        nxt = A[i] - 'a';

        while(k!=T && k->son[nxt] == NULL)
            k = k->up;

        if(k->son[nxt] != NULL)
            k = k->son[nxt];

        k->cnt++;
    }

    get_result(T);

    for(i=1; i<=n; ++i)
        zout<<ans[i]<<'\n';

    return 0;
}