Cod sursa(job #786935)
// Structura de date trie este gestionata ca un arbore cu Sigma fii.
// Fiecare muchie din arbore va reprezenta o litera , iar nodurile vor
// repezenta fii pana la momentul respectiv.
// Implementarea poate varia in functie de nevoi ( viteza sau memorie
// mai mica ). Pentru o memorie mai mica vom folosi o implmentare cu
// vectori pentru a retine minimul de muchii ( ca intr-un graf ), insa
// viteza de gestionare a operatiilor va fi O(L*Sigma) , supraestimata.
// Pentru o viteza mai mare putem gestiona Trie-ul cu Sigma laturi din
// fiecare nod, astfel complexitatea in timp va deveni O(L).
// O a 3-a varianta este gestionarea unei structuri de date implementate
// manual din care sa eliberam memoria cand este nevoie, adica folosirea
// unui vector implementat manual ca sa nu ocupam memorie suplimentara.
// Varianta B: de mana.
#include <fstream>
#include <cstring>
using namespace std;
struct Trie
{
int cont, sons;
Trie *son[ 26 ];
Trie()
{
cont = sons = 0;
memset( son , 0 , sizeof(son) );
}
};
Trie *T = new Trie;
#define CH ( *Act - 'a' )
void Insert(Trie *Nod,char *Act)
{
if ( *Act == '\n' )
{
Nod->cont ++;
return;
}
if ( Nod->son[ CH ] == 0 )
{
Nod->son[ CH ] = new Trie;
Nod->sons ++;
}
Insert( Nod->son[ CH ] , Act+1 );
}
bool Delete(Trie *Nod,char *Act)
{
if ( *Act =='\n' )
{
Nod->cont --;
}
else
if ( Delete( Nod->son[ CH ] , Act+1 ) )
{
Nod->son[ CH ]=0;
Nod->sons --;
}
if ( Nod->cont==0 && Nod->sons==0 && Nod != T )
{
delete Nod;
return 1;
}
return 0;
}
int Count(Trie *Nod,char *Act)
{
if ( *Act == '\n' )
return Nod->cont;
if ( Nod->son[ CH ] )
return Count( Nod->son[ CH ],Act+1 );
return 0;
}
int Find(Trie *Nod,char *Act,int Nbr)
{
if ( *Act == '\n' )
return Nbr;
if ( Nod->son[ CH ] )
return Find( Nod->son[ CH ], Act+1 , Nbr );
return Nbr;
}
#undef CH
ifstream F("trie.in");
ofstream G("trie.out");
const int Nmax = 30;
char Str[Nmax];
int N,Type;
int main()
{
while ( ! F.eof() )
{
F.getline(Str,Nmax,'\n');
Type=Str[0]-'0';
N=strlen(Str);
--N;
switch ( Type )
{
case 0:
{
Insert(T,Str+2);
break;
}
case 1:
{
Delete(T,Str+2);
break;
}
case 2:
{
G<<Count(T,Str+2)<<'\n';
break;
}
case 3:
{
G<<Find(T,Str+2,0)<<'\n';
break;
}
}
}
}