Cod sursa(job #786935)

Utilizator danalex97Dan H Alexandru danalex97 Data 12 septembrie 2012 13:15:48
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.45 kb
// 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;
				}
		}
	}
}