Cod sursa(job #1966102)

Utilizator VladG26Ene Vlad-Mihai VladG26 Data 14 aprilie 2017 21:33:31
Problema Aho-Corasick Scor 95
Compilator cpp Status done
Runda Arhiva educationala Marime 2.66 kb
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <stack>
#include <vector>
using namespace std;
vector <int> ::iterator IT;
struct trie
{
    trie *F[27];
    int ap;
    vector <int> indice;
    trie *fail;
    trie()
    {
        for(int i=0; i<=26; i++)
            F[i]=NULL;
        ap=0;
        indice.clear();
        fail=NULL;
    }
}*root;

int auxCH;
queue<trie*>deBFS;
stack<trie*>intoarcere;
char dictionar[101][10001];
char cuv[1000001];
int v[103];
int n;

void insertTrie(trie* nod,int indice,char cuvant[])
{
    for(char* i=cuvant; *i; i++)
    {
        auxCH=*i-'a';
        if(!nod->F[auxCH])
        {
            nod->F[auxCH]=new trie();
        }
        nod=nod->F[auxCH];
    }
    nod->indice.push_back(indice);
}

void citire()
{
    scanf("%s\n",cuv);
    scanf("%d\n",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%s\n",dictionar[i]);
        insertTrie(root,i,dictionar[i]);
    }
}
void makeFail(trie *nod)
{
    for(int i=0; i<=26; i++)
    {
        if(nod->F[i])
        {
            nod->F[i]->fail=nod;
            deBFS.push(nod->F[i]);
        }
    }
    trie*aux;
    while(!deBFS.empty())
    {
        nod=deBFS.front();
        deBFS.pop();
        for(int i=0; i<=26; i++)
        {
            if(!nod->F[i])
                continue;

            aux=nod->fail;
            deBFS.push(nod->F[i]);
            intoarcere.push(nod->F[i]);

            while(!aux->F[i]&&aux->fail)
                aux=aux->fail;

            if(aux->F[i])
                nod->F[i]->fail=aux->F[i];
            else
                nod->F[i]->fail=root;
        }
    }
}
void solve()
{
    trie*aux;
    while(!intoarcere.empty())
    {
        aux=intoarcere.top();
        intoarcere.pop();

        aux->fail->ap+=aux->ap;

        for(IT=aux->fail->indice.begin();IT!=aux->fail->indice.end();IT++)
            v[*IT]=aux->fail->ap;

        aux=aux->fail;
    }
}
int main()
{
    freopen("ahocorasick.in","r",stdin);
    freopen("ahocorasick.out","w",stdout);
    root=new trie();
    citire();
    makeFail(root);



    trie*nod=root;
    for(char *i=cuv; *i; i++)
    {
        auxCH=*i-'a';
        while(nod&&!nod->F[auxCH])
        {
            nod=nod->fail;
        }

        if(nod)
            nod=nod->F[auxCH];
        else
            nod=root;

        nod->ap++;

        for(IT=nod->indice.begin();IT!=nod->indice.end();IT++)
            v[*IT]=nod->ap;
    }

    solve();

    for(int i=1; i<=n; i++)
    {
        printf("%d",v[i]);
        printf("\n");
    }

    return 0;
}