Cod sursa(job #2493238)

Utilizator DavidLDavid Lauran DavidL Data 16 noiembrie 2019 10:53:30
Problema Aho-Corasick Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.43 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fi("ahocorasick.in");
ofstream fo("ahocorasick.out");/*
#define cin fi
#define cout fo*/

struct Trie {
    int cnt = 0;
    vector <int> ceCuv;
    Trie *fiu[30] = {0};
    Trie *fail = 0;
};

int m, n;
char cuv[10005];
char A[1000005];
int ans[105];
Trie *T = new Trie;


void adauga(Trie *nod, int poz, int careCuv)
{
    if (poz == strlen(cuv + 1))
    {
        nod->cnt++;
        nod->ceCuv.push_back(careCuv);
        return;
    }

    if (nod->fiu[cuv[poz + 1] - 'a'] == 0)
        nod->fiu[cuv[poz + 1] - 'a'] = new Trie;

    adauga(nod->fiu[cuv[poz + 1] - 'a'], poz + 1, careCuv);
}

void getFail()
{
    queue <Trie*> Q;
    for (int i = 0; i < 26; i++)
        if (T->fiu[i])
        {
            T->fiu[i]->fail = T;
            Q.push(T->fiu[i]);
        }

    while (!Q.empty())
    {
        Trie *nod = Q.front(); // ii fac fiii lui nod
        Q.pop();

        for (int i = 0; i < 26; i++)
            if (nod->fiu[i])
            {
                Trie *f = nod->fail;
                while (f != T && f->fiu[i] == 0)
                    f = f->fail;
                
                if (f->fiu[i])
                    f = f->fiu[i];

                nod->fiu[i]->fail = f;
                
                Q.push(nod->fiu[i]);
            }
    }
}

int main()
{
    cin >> A + 1;
    n = strlen(A + 1);
    
    cin >> m;
    for (int i = 1; i <= m; i++)
    {
        cin >> cuv + 1;
        adauga(T, 0, i);
    }
    
    getFail();

    
    int total = 0;
    Trie *curr = T;
    for (int i = 1; i <= n; i++)
    {
        if (curr->fiu[A[i] - 'a'])
        {
            curr = curr->fiu[A[i] - 'a'];
            //total += curr->cnt;
            //continue;
        }
        else
        {
            while (curr != T && curr->fiu[A[i] - 'a'] == 0)
                curr = curr->fail;
            
            if (curr->fiu[A[i] - 'a'])
                curr = curr->fiu[A[i] - 'a'];
        }
        
        Trie *aux = curr;
        //total += aux->cnt;
        while (aux != T)
        {
            total += aux->cnt;
            for (auto x: aux->ceCuv)
                ans[x]++;
            aux = aux->fail;
        }
        //cout << total << " ";
    }
    
    //cout << total;
    for (int i = 1; i <= m; i++)
        cout << ans[i] << "\n";
    

    return 0;
}