Cod sursa(job #604858)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 25 iulie 2011 18:04:05
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.95 kb
#include <fstream>
#include <iostream>
#include <string.h>

#define MAX_CHILDREN 26

using namespace std;

char currentWord[32];

struct TrieData
{
	unsigned short times;
	
	TrieData *parent;
	TrieData *child[MAX_CHILDREN];
};

class CTrie
{
public:
	CTrie()
	{
		Trie.times = 0;
		Trie.parent = NULL;
		memset(Trie.child, 0, sizeof(TrieData*)*MAX_CHILDREN);
	}
	
	void addWord(const char word[])
	{
		TrieData* ptr = &Trie;

		for (int i=0; i<strlen(word); ++i)
		{
			if (!ptr->child[word[i] - 'a'])
			{
				ptr->child[word[i] - 'a'] = allocChild();
				ptr->child[word[i] - 'a']->parent = ptr;
			}
			
			ptr = ptr->child[word[i] - 'a'];
		}
		
		ptr->times++;
	}
	
	void delWord(const char word[])
	{
		int i;
		TrieData *ptr = &Trie, *parent;

		for (i=0; i<strlen(word); ++i)
		{
			if (!ptr->child[word[i] - 'a'])
			{
				return;
			}
			
			ptr = ptr->child[word[i] - 'a'];
		}
		ptr->times--;
		
		i = strlen(word)-1;
		
		while ( ((parent = ptr->parent) != NULL) && (!ptr->times) && (checkHasChildren(ptr) == -1))
		{
			freeChild(ptr);
			parent->child[word[i] - 'a'] = NULL;
			
			ptr = parent;
			i--;
		}
	}
	
	int countWord(const char word[])
	{
		TrieData* ptr = &Trie;

		for (int i=0; i<strlen(word); ++i)
		{
			if (!ptr->child[word[i] - 'a'])
			{
				return 0;
			}
			
			ptr = ptr->child[word[i] - 'a'];
		}
		
		return ptr->times;
	}
	
	int longestPrefix(const char word[])
	{
		int prefix = 0;
		TrieData* ptr = &Trie;

		for (int i=0; i<strlen(word); ++i)
		{
			if (!ptr->child[word[i] - 'a'])
			{
				return prefix;
			}
			
			prefix++;
			ptr = ptr->child[word[i] - 'a'];
		}
		
		return prefix;
	}

private:

	TrieData* allocChild() const
	{
		TrieData* td = new TrieData;
		
		td->times = 0;
		memset(td, 0, sizeof(TrieData*)*MAX_CHILDREN);
		
		return td;
	}
	
	int checkHasChildren(const TrieData *td) const
	{
		for (int i=0; i<MAX_CHILDREN; ++i)
			if (td->child[i])
				return i;
		
		return -1;
	}
	
	void freeChild(TrieData *td)
	{
		delete td;
	}
	
	TrieData Trie;
};

int main()
{
	int op;
	fstream fin("trie.in", fstream::in);
	fstream fout("trie.out", fstream::out);
	CTrie Trie;
	
	while(fin >> op)
	{
		fin >> currentWord;
		
		switch (op)
		{
			case 0:
			{
				//cout << "0 " << currentWord << endl;
				
				Trie.addWord(currentWord);
			}; break;
			
			case 1:
			{
				//cout << "1 " << currentWord << endl;
				Trie.delWord(currentWord);
			}; break;
			
			case 2:
			{
				//cout << "2 " << currentWord << " = " << Trie.countWord(currentWord) << endl;
				
				fout << Trie.countWord(currentWord) << "\n";
			}; break;
			
			case 3:
			{
				//cout << "3 " << currentWord << " = " << Trie.longestPrefix(currentWord) << endl;
				
				fout << Trie.longestPrefix(currentWord) << "\n";
			}; break;
			
			default:
			{
			}
		}
	}
	
	fin.close();
	fout.close();

	return 0;
}