Cod sursa(job #843018)

Utilizator Brz_VladBrezae Vlad Brz_Vlad Data 27 decembrie 2012 12:56:58
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.54 kb
#include <stdio.h>

#define CHARS ('z'-'a'+1)
#define CHAR_INDEX(x) ((x)-'a')

struct Node{
		Node* childs[CHARS];
		int nr_childs;
		int count; // numarului de aparitii ale cuvantului care se termina pe pozitia aceasta
};

class Trie{
	private:
		Node empty_node;
		Node* root;
		
		void AddWordR(char* word, Node* node);
		bool DeleteWordR(char* word, Node* node);
		int GetWordCountR(char* word, Node* node);
		int GetMaximumPrefixR(char* word, Node* node);
		void PrintTrieR(Node* node, int level);
	public:
		Trie();
		
		void PrintTrie();
		void AddWord(char* word);
		void DeleteWord(char* word);
		int GetWordCount(char* word);
		int GetMaximumPrefix(char* word);
};



//    0 w - adauga o aparitie a cuvantului w in lista
//   1 w - sterge o aparitie a cuvantului w din lista
//    2 w - tipareste numarul de aparitii ale cuvantului w in lista
//    3 w - tipareste lungimea celui mai lung prefix comun al lui w cu oricare cuvant din lista


int main(int argc, char* argv[])
{
	freopen("trie.in","r",stdin);
	freopen("trie.out","w",stdout);
	
	int op;
	char word[21];
	
	
	Trie trie;
	
	while( scanf("%d %s",&op,word) > 0 ){
		switch(op){
			case 0:
//				printf("Adaug %s\n",word);
				trie.AddWord(word);
//				trie.PrintTrie();
				break;
			case 1:
//				printf("Sterg %s\n",word);
				trie.DeleteWord(word);
//				trie.PrintTrie();
				break;
			case 2:
				printf("%d\n",trie.GetWordCount(word));
				break;
			case 3:
				printf("%d\n",trie.GetMaximumPrefix(word));
				break;			
		}		
	}
	
	return 0;
}


////////////////////////////////////////
Trie::Trie()
{
	for(int i=0;i<CHARS;i++)
		empty_node.childs[i] = NULL;
	empty_node.nr_childs= 0;
	empty_node.count = 0;
	root = new Node;
	*root = empty_node;
}

void Trie::AddWord(char* word)
{
	AddWordR(word,root);
}

void Trie::DeleteWord(char* word)
{
	DeleteWordR(word,root);
}

int Trie::GetWordCount(char* word)
{
	return GetWordCountR(word,root);
}

int Trie::GetMaximumPrefix(char* word)
{
	return GetMaximumPrefixR(word,root);
}

void Trie::PrintTrie()
{
	PrintTrieR(root,0);
	fflush(stdout);
}

void Trie::AddWordR(char* word, Node* node)
{	
	if( *word == 0 ){
		node->count++;
		return;
	}
	
	if( node->childs[CHAR_INDEX(*word)] == NULL ){
		Node* new_node = new Node;
		*new_node = empty_node;
		
		node->childs[CHAR_INDEX(*word)] = new_node;
		node->nr_childs++;
	}
	
	AddWordR(word+1,node->childs[CHAR_INDEX(*word)]);
}

bool Trie::DeleteWordR(char* word, Node* node)
{
	if( *word == 0 ){
		node->count--;
		if( node->count == 0 && node->nr_childs == 0 ){
			delete node;
			return true;			
		}
		return false;
	}
	
	if( node->childs[CHAR_INDEX(*word)] != NULL ){
		if( DeleteWordR(word+1, node->childs[CHAR_INDEX(*word)]) ){
			node->childs[CHAR_INDEX(*word)] = NULL;
			node->nr_childs--;
			if( node->count == 0 && node->nr_childs == 0 && node != root){
				delete node;
				return true;
			}			
		}		
	}	
	return false;
}

int Trie::GetWordCountR(char* word, Node* node)
{
	if( *word == 0 ){
		return node->count;
	}
	
	if( node->childs[CHAR_INDEX(*word)] != NULL )
		return GetWordCountR(word+1, node->childs[CHAR_INDEX(*word)]);
	else
		return 0;
}

int Trie::GetMaximumPrefixR(char* word, Node* node)
{
	if( *word == 0 )
		return 0;
		
	if( node->childs[CHAR_INDEX(*word)] == NULL )
		return 0;
	else
		return 1+GetMaximumPrefixR(word+1,node->childs[CHAR_INDEX(*word)]);
}

void Trie::PrintTrieR(Node* node,int level)
{
	printf(" %d\n",node->count);
	
	int i,j;
	for(i=0;i<CHARS;i++){
		if( node->childs[i] != NULL ){
			for(j=0;j<level;j++){
				printf("  ");
			}
			printf("%c",i+'a');
			PrintTrieR(node->childs[i],level+1);			
		}		
	}
}