Pagini recente » Cod sursa (job #3282577) | Cod sursa (job #825301) | Cod sursa (job #1095015) | Cod sursa (job #10815) | Cod sursa (job #2404410)
#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;
}