Cod sursa(job #1966081)

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

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(int i=0; i<strlen(cuvant); i++)
    {
        if(!nod->F[*(cuvant+i)-'a'])
        {
            nod->F[*(cuvant+i)-'a']=new trie();
        }
        nod=nod->F[*(cuvant+i)-'a'];
    }
    nod->indice=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();
        if(aux->fail)
        {
            aux->fail->ap+=aux->ap;

            if(aux->fail->indice)
                v[aux->fail->indice]=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(int i=0; i<strlen(cuv); i++)
    {
        while(nod&&!nod->F[*(cuv+i)-'a'])
        {
            nod=nod->fail;
        }

        if(nod)
            nod=nod->F[*(cuv+i)-'a'];
        else
            nod=root;

        nod->ap++;
        if(nod->indice)
            v[nod->indice]=nod->ap;
    }

    solve();

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

    return 0;
}