Pagini recente » Cod sursa (job #2514736) | Cod sursa (job #322934) | Cod sursa (job #2391954) | Cod sursa (job #441182) | Cod sursa (job #2696587)
#include <bits/stdc++.h>
using namespace std;
ifstream f("trie.in");
ofstream g("trie.out");
struct trie
{
int contor_prefix,contor_aparitii,next[26];
};
trie structura_initializare;
vector <trie> v;
int t,lungime_string;
char s[30];
/// dam update => stergem sau adaugam cuvant in trie
void update(int poz_trie,int poz_string, int val)
{
v[poz_trie].contor_prefix += val; /// schimb(+1/-1) aparitia prefixului format pana la poz_string
if(poz_string==lungime_string)
{
/// am ajuns la final
/// in cazul acesta schimb(+1/-1) si numarul de apartii a intregului cuvant
/// evident, nu mai continui mai departe
v[poz_trie].contor_aparitii += val;
return;
}
else
{
/// acum vreau sa merg mai departe
int indice_urmator = int(s[poz_string]-'a');
if(v[poz_trie].next[indice_urmator]==0)
{
/// daca 'spatiul' acesta inca nu este alocat in vectorul meu de trie v
/// creez spatiul si il initializez cu "structura_initializare"
v.push_back(structura_initializare);
t++;
v[poz_trie].next[indice_urmator]=t;
/// t reprezinta numarul total de noduri alocate in trie-ul meu v
}
update(v[poz_trie].next[indice_urmator],poz_string+1,val);
}
}
/// cerinta 1 - aflarea numarului de cuvinte complete
int query1()
{
/// radacina vectorului de trie va fi "zero", adica acel nod tip "structura_initializare"
int poz_trie=0,i;
for(i=0;i<lungime_string;i++)
{
/// parcurg fiecare litera din sirul pe care il caut
int indice_urmator=int(s[i]-'a');
if(v[poz_trie].next[indice_urmator]==0)
{
/// daca nu am alocat spatiul, inseamna ca nu exista cuvantul pe care il caut
/// adica nu i-am dat niciodata "update", implicit o initializare la spatiile de litere pe care sa le ocupe in trie
break;
}
else
{
/// merg mai departe
poz_trie=v[poz_trie].next[indice_urmator];
}
}
if(i==lungime_string)
{
/// daca am ajuns pana la final, atunci inseamna ca exista acest cuvant
return v[poz_trie].contor_aparitii;
}
else return 0;
}
/// cerinta 2 - aflarea celui mai lung prefix comun
int query2()
{
/// aici pornesc de la radacina si iau fiecare caracter al cuvantului pana cand obtin frecventa prefixul <=0
/// NOTA: daca cuvantul "lat" a fost pus in trie, iar eu caut cuvantul "lat" => lungimea este fix tot cuvantul, adica 3
int poz_trie=0,i,poz_trie_urmator;
for(i=0;i<lungime_string;i++)
{
int indice_urmator=int(s[i]-'a');
if(v[poz_trie].next[indice_urmator]==0)
{
/// in cazul acesta este ca la query1 - adica nu am atribuit acel spatiu, deci nu pot sa merg mai departe
break;
}
else
{
/// inseamna ca spatiul exista
poz_trie_urmator = v[poz_trie].next[indice_urmator];
if(v[poz_trie_urmator].contor_prefix<=0)
{
/// evident, daca din start am gasit o litera in prefix care apare de 0 sau mai putin de 0 ori atunci dau break
/// nu mai merg mai departe, fiindca aici mi se termina prefixul
break;
}
else
{
/// merg mai departe
poz_trie=v[poz_trie].next[indice_urmator];
}
}
}
/// i va reprezenta de fapt lungimea maxima pana unde am mers
/// i va incepe de la 0
return i;
}
int tip;
int main()
{
v.push_back(structura_initializare);
/// radacina mea in vectorul trie va fi mereu un nod de tip "zero"
/// evident t=0, initializat global
while(f>>tip>>s)
{
lungime_string=strlen(s);
if(tip==0)update(0,0,1);
else if(tip==1)update(0,0,-1);
else if(tip==2)g<<query1()<<'\n';
else if(tip==3)g<<query2()<<'\n';
}
return 0;
}