Pagini recente » Cod sursa (job #3284663) | Cod sursa (job #3254510) | Cod sursa (job #2711501) | Cod sursa (job #3235973) | Cod sursa (job #669501)
Cod sursa(job #669501)
#include<stdio.h>
#define infile "trie.in"
#define outfile "trie.out"
#define nmax 512*1024
#define lmax 101
char v[lmax]; //vectorul in care citim liniile
struct nod
{
char c; //caracterul nodului
int fi,fr; //pozitia fiu, respectiv frate
int ap,ac; //numarul de aparitii pentru prefix, respectiv cuvant ce se termina aici
} n[nmax]; //nodurile trie-ului
int nrn; //numarul de noduri ocupate
void add()
{ //adaugam o aparitie a cuvantului in lista :P
int i,j,k=0,r=0; //r-radacina arborelui (trie)
for(i=2;v[i]&&v[i]!='\n';i++) //trebuie luate toate caracterele si puse in trie (daca nu exista)
{
for(j=n[r].fi;j;j=n[j].fr) //trecem pe la toti copii radacinei ;))
if(n[j].c==v[i]) //am gasit caracterul ;))
{
n[j].ap++; //crestem numarul de aparitii pt prefix
if(!v[i+1]||v[i+1]=='\n') n[j].ac++; //inseamna ca avem si o aparitie de cuvant :P
r=j; //acest nod devine radacina pt nivelul urmator :P
break; //am gasit...oprim cautarea:P
}
else k=j; //pt a sti fratele anterior daca nu gasim caracterul :P
if(!j) //inseamna k nu am gasit...deci trebuie sa adaugam :P
{
nrn++; //facem loc pt noul nod
n[nrn].c=v[i]; //salvam caracterul
n[nrn].ap=1; //avem o aparitie pt prefix
if(!v[i+1]||v[i+1]=='\n') n[nrn].ac=1; else n[nrn].ac=0; //daca se termina cuvant aici, sau nu
if(!n[r].fi) n[r].fi=nrn; //inseamna ca tatal nu are niciun fiu, deci acesta va deveni fiu
else n[k].fr=nrn; //altfel, ultimul frate, va avea legatura catre acest nou frate
r=nrn; //acest nod va fi radacina pt nivelul urmator :P
}
}
}
void del()
{ //sterge o aparitie a cuvantului din lista
int i,j,r=0; //r-radacina trie-ului
for(i=2;v[i]&&v[i]!='\n';i++) //toate caracterele cuvantului
for(j=n[r].fi;j;j=n[j].fr) //trecem pe la toti copii
if(n[j].c==v[i]) //am gasit caracterul
{
n[j].ap--; //scadem prefixul
if(!v[i+1]||v[i+1]=='\n') n[j].ac--; //se termina cuvantul...deci scadem si aparitia de cuvant ;))
r=j; //se schimba radacina ;))
break; //oprim cautarea mai departe
}
}
int ap()
{ //returneaza numarul de aparitii ale cuvantului
int i,j,r=0; //r-radacina :P
for(i=2;v[i]&&v[i]!='\n';i++) //toate caracterele la rand
{
for(j=n[r].fi;j;j=n[j].fr) //trecem pe la toti fii radacinei
if(n[j].c==v[i]&&n[j].ap) //inseamna ca am gasit caracterul de la aceasta pozitie
{
r=j; //se schimba radacina ;))
if(!v[i+1]||v[i+1]=='\n') return n[r].ac; //returnam numarul de aparitii ale cuvantului
break; //daca nu este inca sfarsitul cuvantului, oprim cautarea
}
if(!j) return 0; //inseamna ca nu am gasit, oprim cautarea si returnam 0
}
return 0; //nu a fost gasit ;))
}
int lu()
{ //returneaza lungimea celui mai lung prefix cu oricare alt cuvant din trie
int i,j,r=0; //r-radacina trie-ului
int l=0; //lungimea :P
for(i=2;v[i]&&v[i]!='\n';i++) //luam toate caracterele
{
for(j=n[r].fi;j;j=n[j].fr) //trecem pe la toti copii
if(n[j].c==v[i]&&n[j].ap) //am gasit caracter pe acest nivel
{
l++; //crestem lungimea
r=j; //se schimba radacina ;))
break; //oprim cautarea
}
if(!j) return l; //inseamna ca nu am gasit....deci afisem lungimea gasita pana acum ;))
}
return l; //in cazul in care a fost gasita in intregime ;))
}
int main()
{
freopen(infile,"r",stdin);
freopen(outfile,"w",stdout);
while(fgets(v,lmax,stdin))
{ //cat timp citim ;))
if(v[0]=='0') add(); //adaugam o aparitie
if(v[0]=='1') del(); //stergem o aparitie
if(v[0]=='2') printf("%d\n",ap()); //afisem numarul de aparitii ale cuvantului
if(v[0]=='3') printf("%d\n",lu()); //afisem cel mai lung prefix al sau cu oricare alt cuvant
//for(int j=1;j<=nrn;++j)
//printf("%c %d %d\n",n[j].c,n[j].fi,n[j].fr);
//printf("\n");
}
fclose(stdin);
fclose(stdout);
return 0;
}