Cod sursa(job #2507418)

Utilizator vladvlad00Vlad Teodorescu vladvlad00 Data 10 decembrie 2019 11:06:56
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
#include <fstream>
#include <vector>
#include <cstring>
#define pb push_back

using namespace std;

ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

struct aho
{
    vector<int> siruri; //indicii cuv care se termina aici
    aho *fii[26], *fail;
    int potriv;

    aho()
    {
        potriv = 0;
        fail = 0;
        memset(fii,0,sizeof(fii));
    }
};

void ins(aho *t, char *s, int x);
void BFS(aho *t);
void antiBFS(aho *t);

int n, in, sf, rez[105];
char A[1000005], cuv[10005];
aho *t = new aho;
aho *Q[1000005];

int main()
{
    fin >> A;
    fin >> n;
    for (int i=1;i<=n;i++)
    {
        fin >> cuv;
        ins(t,cuv,i);
    }
    BFS(t);
    aho *p = t;
    int lg = strlen(A);
    for (int i=0;i<lg;i++)
    {
        int urm = A[i]-'a';
        while (!p->fii[urm] && p!=t)
            p = p->fail;
        if (p->fii[urm])
            p = p->fii[urm];
        p->potriv++;
    }
    antiBFS(t);
    for (int i=1;i<=n;i++)
        fout << rez[i] << '\n';
    return 0;
}

void ins(aho *t, char *s, int x)
{
    if (*s == 0)
        t->siruri.pb(x);
    else
    {
        int urm = *s-'a';
        if (!t->fii[urm])
            t->fii[urm] = new aho;
        ins(t->fii[urm],s+1,x);
    }
}

void BFS(aho *t)
{
    aho *aux, *faill;
    in=0;
    sf=0;

    t->fail = t; //radacina se duce la ea insasi
    Q[sf++] = t;
    while (in < sf)
    {
        aux = Q[in++];
        for (int i=0;i<26;i++)
            if (aux->fii[i])
            {
                //incercam sa ii gasim failul fiului i
                faill = aux->fail;
                while (faill != t && !faill->fii[i]) //parurgem sufixe pana unul are ultima litera a nodului
                    faill = faill->fail;
                if (faill->fii[i] && faill->fii[i] != aux->fii[i]) //sa nu fac bucla
                    faill = faill->fii[i];
                aux->fii[i]->fail = faill;
                Q[sf++] = aux->fii[i];
            }
    }
    t->fail = 0;
}

void antiBFS(aho *t)
{
    aho *aux;
    for (int i=sf-1;i>=0;i--)
    {
        aux = Q[i];
        if (aux->fail)
            aux->fail->potriv += aux->potriv;
        for (int v:aux->siruri)
            rez[v] = aux->potriv;
    }
}