Pagini recente » Cod sursa (job #1058402) | Cod sursa (job #2466145) | Cod sursa (job #2452741) | Cod sursa (job #2941166) | Cod sursa (job #710838)
Cod sursa(job #710838)
#include<cstdio>
#include<cstring>
using namespace std;
// ch va retine un numar int
// el va indica pozitia in alfabet a literei date
// a - a = 0 // prima litera
// b - a = 1 // a doua litera
// l - a = 11 // a 11-a litera etc.
#define ch (*s - 'a')
// Trie-ul:
struct Trie
{
int cuvinte; // numarul de cuvinte de la nodul respectiv in josul triei
int nrfii; // numarul de ramificatii din nodul respectiv == litere distincte
Trie *edge[26]; // sunt 26 litere "a...z" fara diacritice
Trie() // initializarea Trie-ului se va face la fiecare new Trie
{
cuvinte = 0;
nrfii = 0;
memset(edge, 0, sizeof(edge));
}
};
Trie *T = new Trie;
// Cele 4 functii:
void inserare(Trie *nod, char *s); // inserare
int stergere(Trie *nod, char *s); // stergere
int nr_cuvinte(Trie *nod, char *s); // numara cuvintele
int l_prefix(Trie *nod, char *s, int k); // numara lungimea prefixul
int main ()
{
freopen("trie.in","r",stdin);
freopen("trie.out","w",stdout);
int r;
char line[32];
fgets(line, 32, stdin);
while(!feof(stdin))
{
switch(line[0])
{
// line+2 == de aici incepe cuvantul
case '0': inserare(T, line+2); break;
case '1': stergere(T, line+2); break;
case '2': r = nr_cuvinte(T, line+2), printf("%d\n", r); break;
case '3': r = l_prefix(T, line+2, 0), printf("%d\n", r); break;
}
fgets(line, 32, stdin);
}
return 0;
}
void inserare(Trie *nod, char *s)
{
if(*s == '\n') { nod->cuvinte++; return; } // daca se termina de parcurs *s
if(nod->edge[ch]==0)
{ // daca *s este un cuvant care se repeta atunci
nod->edge[ch] = new Trie; // va creste nr de cuvinte din nodul ultimei litere
nod->nrfii++;
}
inserare(nod->edge[ch], s+1); // astfel se trece prin fiecare litera a cuvantului
}
int stergere(Trie *nod, char *s)
{
if(*s == '\n') nod->cuvinte--; // asta e pentru cazurile in care cuvantul dat spre stergere
// este inclus in intregime in prefixul comun al altora
// exemplu: *s==tra si in trie se afla "trabant"
// ramura "trabant", in loc sa contina 2 cuvinte va contine doar 1
else if(stergere(nod->edge[ch], s+1)) // se parcurge astfel cuvantul, litera cu litera
{
nod->edge[ch] = 0;
nod->nrfii--;
}
if(nod != T && nod->cuvinte == 0 && nod->nrfii == 0) // si cand se ajunge la ultima litera o sterge
{ // apoi penultima litera a devenit ultima litera
delete nod; // si o sterge pana la radacina comuna cu alt cuvant
return 1; // daca exista sau pana la radacina triei
}
return 0;
}
int nr_cuvinte(Trie *nod, char *s)
{
if(*s == '\n') return nod->cuvinte; // nr de aparitii ale unui cuvant se afla in nodul ultimei sale litere
if(nod->edge[ch])
return nr_cuvinte(nod->edge[ch], s+1);
return 0;
}
int l_prefix(Trie *nod, char *s, int k)
{
if(*s == '\n' || nod->edge[ch] == 0) return k;
return l_prefix(nod->edge[ch], s+1, k+1);
}