Cod sursa(job #2011259)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 15 august 2017 18:18:16
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.62 kb
#include <fstream>
#include <string.h>
#define lcuv 10001
#define ltext 1000001
#define alf 25
using namespace std;
fstream f1 ("ahocorasick.in", ios::in);
fstream f2 ("ahocorasick.out", ios::out);
char text[ltext], cuv[lcuv];
int n;
long int prim=1, ultim=0, k=0, rez[101];
struct trie
{
    trie * ch[alf+1];
    trie *nods;
    long int contor;
    int nrcuv, v[101];
}* rad, * coada[ltext];
void creare(trie *&nod)
{
    nod= new trie;
    nod->nods=0;
    nod->nrcuv=0;
    nod->contor=0;
    for(int i=1; i<=n; i++)
        nod->v[i]=0;
    for(int i=0; i<=alf; i++)
        nod->ch[i]=0;
}
void adauga(trie *nod, char *cuv, int in)
{
    if(*cuv!=0)
    {
        if(nod->ch[*cuv-'a']==0) creare(nod->ch[*cuv-'a']);
        adauga(nod->ch[*cuv-'a'], cuv+1, in);
    }
    else {nod->nrcuv++;nod->v[nod->nrcuv]=in;}
}
void citire()
{
    f1>>text>>n;
    creare(rad);
    for(int i=1; i<=n; i++)
    {
        f1>>cuv;
        adauga(rad, cuv, i);
    }
}
void init()
{
    int i;
    for(i=0; i<=alf; i++)
        if(rad->ch[i]!=0)
    {
        k++;
        ultim++;
        coada[ultim]=rad->ch[i];
        rad->ch[i]->nods=rad;
    }
}
void sar()
{
    while(k!=0)
    {
      for(int i=0; i<=alf; i++)
        if(coada[prim]->ch[i]!=0) ///pt fiecare fiu al nodului curent
        {
            ultim++; k++;            ///pui fiul in coada
            coada[ultim]=coada[prim]->ch[i];
                                  ///determini nodul saritura pt fiu
            trie * sar=coada[prim]->nods;
            while((sar!=rad)&&(sar->ch[i]==0))
                  sar=sar->nods;

            if(sar->ch[i]!=0) coada[ultim]->nods=sar->ch[i];
            else coada[ultim]->nods=rad;
        }

      prim++;                     ///elimini nodul curent
      k--;
    }
}
void sarituri()
{
    init();
    sar();
}
void cauta(trie *&nod, char c)
{
     while((nod!=rad)&&(nod-> ch[c-'a']==0))
        nod=nod->nods;
     if(nod-> ch[c-'a']!=0)
     {
         nod=nod-> ch[c-'a'];
         nod->contor++;
     }
}
void mergi_text()
{
    long int i, l=strlen(text);
    trie*nod=rad;
    for(i=0; i<l; i++)
        cauta(nod, text[i]);
}
void afisare()
{
    while(ultim>0)
    {
        coada[ultim]->nods->contor+=coada[ultim]->contor;
        for(int i=1; i<=coada[ultim]->nrcuv; i++)
            rez[coada[ultim]->v[i]]+=coada[ultim]->contor;
        ultim--;
    }
    for(int i=1; i<=n; i++)
        f2<<rez[i]<<"\n";
}
int main()
{
    std::ios::sync_with_stdio(false);
    citire();
    sarituri();
    mergi_text();
    afisare();
    return 0;
}