Cod sursa(job #2348710)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 19 februarie 2019 21:51:58
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.38 kb
#include <cstdio>
#include <deque>
#include <vector>
#define NRCUV 101
#define DIM_SMOL 10010
#define DIM_BIG 1000010
using namespace std;
struct trie {
    int arrival;
    trie *link; /// link este muchia aia care se duce in sus
    vector <trie *> v;
    trie *f[26];
    trie (){
        arrival=0;
        link=0;
        for (int i=0;i<26;i++)
            f[i]=0;
        v.clear();
    }
};
trie *ending[NRCUV];
deque <trie *> dq;
char s[NRCUV][DIM_SMOL],initial[DIM_BIG];
trie *r=new trie;
trie *root=r;
trie *update (int poz,trie *&r,int i) {
    if (s[poz][i]!=0){
        if (r->f[s[poz][i]-'a']==NULL){
            r->f[s[poz][i]-'a']=new trie;
        }
        return update (poz,r->f[s[poz][i]-'a'],i+1);
    }
    else return r;
}
void dfs (trie *nod){
    int i;
    for (i=0;i<nod->v.size();i++){
        dfs (nod->v[i]);
        nod->arrival+=nod->v[i]->arrival;
    }
}
int main()
{
    FILE *fin=fopen ("ahocorasick.in","r");
    FILE *fout=fopen ("ahocorasick.out","w");
    int n,i;
    trie *nod,*ant;
    fscanf (fin,"%s\n",initial);
    fscanf (fin,"%d\n",&n);
    /// etapa 1 : build trie

    for (i=1;i<=n;i++){
        fscanf (fin,"%s\n",s[i]);
        ending[i]=update (i,root,0);
    }

    /// etapa 2 : faci link urile (bfs pe trie)
    dq.push_back(root);
    while (!dq.empty()){
        nod=dq.front();
        dq.pop_front();
        for (i=0;i<26;i++){
            if (nod->f[i]){
                ant=nod->link;
                while (ant && ant->f[i]==NULL){
                    ant=ant->link;
                }
                if (ant==0)
                    nod->f[i]->link=root;
                else nod->f[i]->link=ant->f[i];
                nod->f[i]->link->v.push_back(nod->f[i]); /// v e reverse-ul lui link
                dq.push_back(nod->f[i]);
            }
        }
    }

    /// etapa 3 : parcurgerea sirului mare si mergand in trie in ac timp

    nod=root;

    for (i=0;initial[i]!=0;i++){
        while (nod!=root && nod->f[initial[i]-'a']==NULL)
            nod=nod->link; /// asemanator cu pasul anterior
        if (nod->f[initial[i]-'a']!=NULL)
            nod=nod->f[initial[i]-'a'];
        nod->arrival++;
    }

    /// etapa 4 : sume partiale pe link uri in trie
    dfs (root);

    for (i=1;i<=n;i++)
        fprintf (fout,"%d\n",ending[i]->arrival);
    return 0;
}