Cod sursa(job #2011200)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 15 august 2017 16:13:28
Problema Aho-Corasick Scor 75
Compilator cpp Status done
Runda Arhiva educationala Marime 2.55 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, f[101];
struct trie
{
    trie * ch[alf+1];
    trie *nods;
    long int word[101];
}* rad, * coada[ltext];
void creare(trie *&nod)
{
    nod= new trie;
    nod->nods=0;
    for(int i=1; i<=n; i++)
        nod->word[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->word[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;
                                   ///la ap cuv ce se termina in fiu adaugi ap cuv ce se termina in saritura fiului (un fel de pref)
            for(int j=1; j<=n; j++)
                coada[ultim]->word[j]+=coada[ultim]->nods->word[j];
        }

      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'];

    for(int i=1; i<=n; i++)
             if(nod->word[i])
                f[i]++;
}
void afisare()
{
    long int l=strlen(text), i;
    int j;
    trie *nod =rad;
    for(i=0; i<l;i++)
        cauta(nod, text[i]);

    for(j=1; j<=n; j++)
        f2<<f[j]<<"\n";
}
int main()
{
    std::ios::sync_with_stdio(false);
    citire();
    sarituri();
    afisare();
    return 0;
}