Pagini recente » Cod sursa (job #1327134) | Cod sursa (job #3151039)
#include <bits/stdc++.h>
using namespace std;
ifstream f("trie.in");
ofstream g("trie.out");
char cuv[25];
int tip;
struct nod
{
int cnt,nr;/// cate cuvinte se termina in acest nod
nod *s[26];/// lista succesorilor nodului ( de la 'a' la 'z' )
/// contructor ... folosim pentru ca un nod construit sa aiba initial cnt=nr=0 si s[i]=NULL
nod()
{
cnt=nr=0;
for(int i=0;i<26;i++)
s[i]=NULL;
}
};
nod *root;
int main()
{
root=new nod;
/// nu stiu cate operatii am deci controlez din citiri cate operatii am !!!
while(f>>tip) /// cat timp pot citi ceva din fisier, acel ceva este tipul operatiei
{
/// citesc cuvantul caruia i se aplica operatia
f>>cuv;
if(tip==0)///insertie cuvant
{
nod *X=root; /// cu X parcurg trie
char *p=cuv; /// cu p parcurg cuvantul
while(*p)/// cat timp am litera ( nu am parcurs inca cuvantul )
{
int i=*p-'a';/// i = "numarul de ordine al literei" ( intre 0='a' si 25='z' )
/// verific daca am deja link spre acea litera si daca nu am creez
if(X->s[i]==NULL) X->s[i]=new nod;
X=X->s[i];/// avansez in trie spre acea litera
X->nr++;///
p++;/// trec la urmatoarea litera urmatoare
}
X->cnt++; /// la nodul la care am ajuns adaug inca o aparitie a cuvantului
}
if(tip==1)/// stergere cuvant
{
nod *X=root; /// cu X parcurg trie
char *p=cuv; /// cu p parcurg cuvantul
while(*p)
{
int i=*p-'a';
X=X->s[i];
X->nr--;
p++;
}
X->cnt--;
}
if(tip==2)/// numara aparitii cuvant
{
nod *X=root; /// cu X parcurg trie
char *p=cuv; /// cu p parcurg cuvantul
while(*p)
{
int i=*p-'a';
X=X->s[i];
if(X==NULL||X->nr==0)
break;
p++;
}
if(X==NULL)
g<<"0\n";
else
g<<X->cnt<<'\n';
}
if(tip==3)/// calculeaza lungime prefix maxim comun cu cuvintele din trie
{
nod *X=root; /// cu X parcurg trie
char *p=cuv; /// cu p parcurg cuvantul
int lg=0;
while(*p)
{
int i=*p-'a';
X=X->s[i];
if(X==NULL||X->nr==0)
break;
p++;lg++;
}
g<<lg<<'\n';
}
}
return 0;
}
/// initial trie vid <=> radacina este NULL !!!
/// operatii:
/// adauga cuvant:
/// plecam din radacina si parcurgem simultan cuvantul si trie
/// cand sunt intr-un nod:
///verific daca nodul are creata legatura spre litera la care am ajuns
/// daca nu are se creaza
/// avansez in trie pe acea legatura
/// avansez in cuvant la urmatoarea litera
/// cand am ajuns la finalul cuvantului - adaug o unitate la contorul nodului
/// numara aparitiile unul cuvant dat
/// se parcurge simultan cuvantul si trie
/// daca la un moment dat nu am legatura spre litera la care am ajuns in cuvant,
/// atunci nu exista cuvantul in trie - numarul de aparitii este 0
/// daca ajung la ultima litera atunci contorul din nodul la care am ajuns indica
/// de cate ori apare cuvantul
/// calculeaza prefixul maxim comun al unui cuvant
/// se parcurg simultan cuvantul si trie
/// pentru fiecare litera pe care o parcurg adaug o unitate la lungimea prefixului
/// daca am terminat cuvantul sau nu am legatura spre litera la care am ajuns ma opresc
/// si afisez lungimea calculata
/// sterge cuvant
/// se parcurge simultan cuvantul si trie
/// scad o unitate din contor
/// OPTIMIZARE LA STERGERE
/// adaug un camp la nod care numara cate cuvinte trec prin nod
/// atunci cand sterg cuvantul scad o unitate din valaorea acelui camp
/// daca valoarea ajunge la 0 atunci pe acolo nu mai trece niciun cuvant
/// orice nod care are acea valoare 0 poate fi "eliminat" din trie