Cod sursa(job #2332861)

Utilizator robx12lnLinca Robert robx12ln Data 31 ianuarie 2019 12:48:49
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2 kb
#include<bits/stdc++.h>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

struct trie{
    int sol;
    trie *f[26];
    trie *back_link;
    vector< trie* > edge;

    trie(){
        sol = 0;
        for( int i = 0; i < 26; i++ )
            f[i] = NULL;
        back_link= NULL;
    }

};
trie *P_word[105], *root, *nod, *aux;
queue< trie* > q;

trie *add_trie( trie *nod, char *s ){
    if( *s == 0 )
        return nod;

    if( nod->f[ *s - 'a'] == NULL )
        nod->f[ *s - 'a'] = new trie();

    return add_trie( nod->f[*s - 'a'], s + 1 );
}

int nr;
char S[1000005], cuv[10005];

void dfs( trie *nod ){
    for( int i = 0; i < nod->edge.size(); i++ ){
        dfs( nod->edge[i] );
        nod->sol += nod->edge[i]->sol;
    }
}

int main(){

    root = new trie();

    fin.getline( S, 1000003 );
    fin >> nr; fin.get();
    for( int i = 1; i <= nr; i++ ){
        fin.getline( cuv, 10003 );
        P_word[i] = add_trie( root, cuv );
    }

    q.push( root );
    while( !q.empty() ){
        nod = q.front();
        q.pop();

        for( int i = 0; i < 26; i++ ){
            if( nod->f[i] == NULL )
                continue;

            aux = nod->back_link;
            while( aux != NULL && aux->f[i] == NULL )
                aux = aux->back_link;

            if( aux == NULL )
                nod->f[i]->back_link = root;
            else
                nod->f[i]->back_link = aux->f[i];

            nod->f[i]->back_link->edge.push_back( nod->f[i] );
            q.push( nod->f[i] );
        }
    }

    nod = root; int L = strlen( S );
    for( int i = 0; i < L; i++ ){
        while( nod != root && nod->f[ S[i] - 'a' ] == NULL )
            nod = nod->back_link;

        if( nod->f[ S[i] - 'a' ] != NULL )
            nod = nod->f[ S[i] - 'a' ];
        nod->sol++;
    }

    dfs( root );
    for( int i = 1; i <= nr; i++ )
        fout << P_word[i]->sol << "\n";
    return 0;
}