Cod sursa(job #2404410)

Utilizator KemyKoTeo Virghi KemyKo Data 12 aprilie 2019 18:38:36
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.55 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

ifstream f("trie.in");
ofstream g("trie.out");

typedef unsigned int ui;
struct TNod{
/*
    index       -> index-ul urmatorului nod de dupa 'val' <=> trie[index]
    nrCuv       -> numarul de aparitii ale cuvantului curent (daca 'val' este la final de cuvant)
    nrAparitii  -> numarul de aparatii ale secventei de caractere pana la 'val' din cuvantul curent
*/
    ui index, nrCuv, nrAparitii;
    char val;

    //initialisation list
    TNod(ui index, ui nrCuv, ui nrAparitii, ui val):
        index(index), nrCuv(nrCuv), nrAparitii(nrAparitii), val(val)
    {
    }
};
vector < vector < TNod > > trie; //la fel ca la orice arbore: vector <int> arb[NMAX];

ui K;           //ultimul index folosit pentru trie
string str;     //citeste enuntul :)

int main()
{
    //lucrand cu obiecte / clase, emplace_back e mai rapid (explicit conversions)
    trie.emplace_back(vector <TNod>());

    ui op, i, j, sz, n, nod, nr;
    bool ok;
    while( f >> op >> str ){
        n = str.size();
        nr = nod = j = 0;  //j -> string, nod -> trie

        switch(op){
            case 0: //adauga o aparitie a cuvantului str in lista
                while(j < n){
                    ok = false;

                    sz = trie[nod].size();
                    for(i=0; i<sz; ++i)
                        if(trie[nod][i].val == str[j])
                            {ok = true; break;}
                    //cout << i << ' ' << j << ' ' << ok << ' ' << nod << ' ' << str << '\n';
                    if(ok){
                        ++trie[nod][i].nrAparitii;
                        if(j == n-1)
                            ++trie[nod][i].nrCuv;

                        ++j;                        //index urmator in string
                        nod = trie[nod][i].index;   //index urmator in trie

                    }
                    /*
                    daca s[j] nu a fost gasit parcurgand arborele trie in acelasi timp cu string-ul,
                    se adauga (lipeste) s[j] la ultimul nod atins in parcurgerea arborelui de pana acum
                    */
                    else {
                        trie.emplace_back(vector <TNod>());
                        trie[nod].emplace_back(
                                    ++K,                    //index
                                    (j == n-1) ? 1 : 0,     //nrCuv
                                    1,                      //nrAparitii
                                    str[j]                  //char val
                                );

                        nod = K;        //index urmator in trie
                        ++j;            //index urmator in string
                    }

                }

                break;
            case 1: //sterge o aparitie a cuvantului str din lista
            case 2: //tipareste numarul de aparitii ale cuvantului str in lista
            case 3: //tipareste lungimea celui mai lung prefix comun al lui str cu oricare cuvant din lista
            //1, 2, 3 impart aceeasi parcurgere (la fel ca si 0, insa adaugare ocupa randuri)

                while(j < n){
                    ok = false;

                    sz = trie[nod].size();
                    for(i=0; i<sz; ++i)
                        if(trie[nod][i].val == str[j])
                            {ok = true; break;}

                    if(ok){
                        if(trie[nod][i].nrAparitii > 0)
                            ++nr;

                        if(op == 1)         //stergere
                            --trie[nod][i].nrAparitii;

                        if(j == n-1){
                            if(op == 2)     //afis nr cuvinte
                                g << trie[nod][i].nrCuv << '\n';
                            else if(op==3)  //afis lungime max comuna
                                g << nr << '\n';
                            else if(op==1)  //sterge si aparitia cuvantului
                                --trie[nod][i].nrCuv;
                        }

                        nod = trie[nod][i].index;
                        ++j;
                    }
                    else {
                        if(op == 2 && j < n)
                            g << "0\n";
                        else if(op == 3)
                            g << nr << '\n';

                        break;  //exit the while loop
                    }

                }

                break;
        }
    }

    return 0;
}