Cod sursa(job #2526347)

Utilizator mirceaisherebina mircea mirceaishere Data 18 ianuarie 2020 15:20:09
Problema Aho-Corasick Scor 5
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.08 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

struct trie{
    int sol;
    trie *f[26];
    trie *back;
    vector <trie *>v;
    /// in v tin nodurile care il au pe nodul curent la back
    trie(){
        sol=0;
        for(int i=0; i<26; i++){
            f[i]=NULL;
        }
        back=0;
        v.clear();
    }
};

int n, m, t, i, j;
char a[1000010], s[10010];
queue <trie *> q;
trie *radacina = new trie();
trie *w[110], *nod, *k;
/// in w tin minte pozitia elementului i din sirul original in trie

trie *AdaugaCuvant(trie *nod, char *text){
    if(*text!=0){
        /// verific daca exista deja litera aceea, iar daca nu, o adaug
        if(nod->f[*text-'a']==NULL){
            nod->f[*text-'a']=new trie;
        }
        AdaugaCuvant(nod->f[*text-'a'], text+1);
    }else{
        return nod;
    }
}


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


int main(){
    fin>>a;
    fin>>n;
    for(i=1; i<=n; i++){
        fin>>s;
        w[i]=AdaugaCuvant(radacina, s);
    }
    q.push(radacina);
    while(!q.empty()){
        nod=q.front();
        q.pop();
        for(i=0; i<26; i++){
            if(nod->f[i]){
                k=nod->back;
                while(k!=0 && !(k->f[i])){
                    k=k->back;
                }
                if(k==0){
                    nod->f[i]->back=radacina;
                }else{
                    nod->f[i]->back=k;
                }
                nod->f[i]->back->v.push_back(nod->f[i]);
                q.push(nod->f[i]);
            }
        }
    }
    k=radacina;
    for(i=0; a[i]; i++){
        while(k!=radacina && !(k->f[ a[i]-'a' ])){
            k=k->back;
        }
        if(k->f[ a[i]-'a' ]){
            k=k->f[ a[i]-'a' ];
        }
        k->sol++;
    }
    dfs(radacina);
    for(i=1; i<=n; i++){
        fout<<w[i]->sol<<"\n";
    }
}