Cod sursa(job #1213297)

Utilizator mariusn01Marius Nicoli mariusn01 Data 27 iulie 2014 19:15:48
Problema Aho-Corasick Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <fstream>
#include <iostream>
#include <queue>

using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

struct trie {
    trie *back;
    int nr;
    vector<trie*> v;
    trie *f[26];

    trie () {
        back = 0;
        nr = 0;
        for (int i=0;i<26;i++)
           f[i] = 0;
    }
};

trie *R = new trie;
trie *nod, *aux;
char S[1000010];
char buff[10010];
trie *L[101];
queue<trie *> Q;

int i, n;

void add(char *sir, trie *r) {
    if (*sir == 0) {
        L[i] = r;
        return;
    }
    if (!r->f[*sir-'a']) {
        r->f[*sir-'a'] = new trie;
    }
    add(sir+1, r->f[*sir-'a']);
}

void df(trie *nod) {
    for (int i=0;i<nod->v.size();i++) {
        df(nod->v[i]);
        nod->nr += nod->v[i]->nr;
    }
//    cout<<nod->nr<<" ";
}

int main() {
    fin>>S;
    fin>>n;
    // construiesc trie cu cuvintele
    for (i=1;i<=n;i++) {
        fin>>buff;
        add(buff, R);
    }

    // construiesc arcul de intoarcere
    Q.push(R);
    while (!Q.empty()) {
        nod = (trie *)Q.front();
        Q.pop();
        for (int i=0;i<26;i++)
            if (nod->f[i]) {
                aux = nod->back;
                while (aux!=0 && aux->f[i] == 0)
                    aux = aux->back;
                if (aux == 0)
                    nod->f[i]->back = R;
                else {
                    nod->f[i]->back = aux->f[i];
                    //nod->f[i]->nr = 1;
                }
                nod->f[i]->back->v.push_back(nod->f[i]);
                Q.push(nod->f[i]);
            }
    }

    // traversez sirul si memorez potrivirile
    nod = R;
    for (i=0;S[i];i++) {
        while (nod!=0 && !nod->f[S[i]-'a'])
            nod = nod->back;
        if (nod == 0)
            nod = R;
        else {
            nod = nod->f[S[i]-'a'];
            nod->nr ++;
        }
    }

    df(R);

    for (i=1;i<=n;i++)
        fout<<L[i]->nr<<"\n";

    return 0;
}