Cod sursa(job #455189)

Utilizator tomescu_alinTomescu Alin tomescu_alin Data 13 mai 2010 09:56:12
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.19 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
using namespace std;

const unsigned int ALPHABET_SIZE = 26;

class Node
{
	public:
		Node()
			:	numChildren(0), count(0)
		{
			memset(child, 0, sizeof(child));
		}
		
		/**
		 *	Deleting a node will delete the tree rooted at that node.
		 */
		~Node()
		{
			for(unsigned int i = 0; i < ALPHABET_SIZE; i++)
				if(child[i])
					delete child[i];
		}
		
	public:
		int numChildren, count;
		Node * child[ALPHABET_SIZE];
};

class Trie
{
	public:
		Trie() : root(new Node) {}
		~Trie() { delete root; }
		
	public:
		void insert(const std::string& word)
		{
			const char * ptr = word.c_str();
			Node * node = root;
			
			while(*ptr && node->child[offset(*ptr)])
			{
				node = node->child[offset(*ptr)];
				ptr++;
			}
			
			if(*ptr == 0)
			{
				node->count++;
			}
			else
			{
				/**
				 *	Insert the remaining characters.
				 */
				while(*ptr)
				{
					node->numChildren++;
					node->child[offset(*ptr)] = new Node;
					
					node = node->child[offset(*ptr)];
					ptr++;
				}
				
				node->count++;
			}
		}
		
		void remove(const std::string& word)
		{
			removeRecursive(root, word.c_str());
		}
		
		int getCount(const std::string& word)
		{
			const char * ptr = word.c_str();
			Node * node = root;
			
			while(*ptr && node->child[offset(*ptr)])
			{
				node = node->child[offset(*ptr)];
				ptr++;
			}
			
			if(*ptr == 0)
				return node->count;
			else
				return 0;
		}
		
		int getLongestPrefixLength(const std::string& word)
		{
			const char * ptr = word.c_str();
			Node * node = root;
			int length = 0;
			
			while(*ptr && node->child[offset(*ptr)])
			{
				node = node->child[offset(*ptr)];
				ptr++;
				length++;
			}
			
			return length;
		}
		
	private:
		int offset(char c) { return c - 'a'; }
		
		bool removeRecursive(Node * node, const char * ptr)
		{
			if(*ptr == 0)
			{
				node->count--;
			}
			else if(removeRecursive(node->child[offset(*ptr)], ptr + 1))
			{
				node->child[offset(*ptr)] = 0;
				node->numChildren--;
			}
			
			if(node->count == 0 && node->numChildren == 0 && node != root)
			{
				delete node;
				return true;
			}
			else
				return false;
		}
		
		int getCountRecursive(Node * node, const char * ptr)
		{
			if(*ptr == 0)
				return node->count;
			
			int index = offset(*ptr);
			
			if(node->child[index])
				return getCountRecursive(node->child[index], ptr + 1);
			else
				return 0;
		}
		
	private:
		Node * root;
};

int main(int argc, char * argv[]) 
{
	
	const char * inFile = "trie.in";
	const char * outFile = "trie.out";
	
	ifstream fin(inFile);
	ofstream fout(outFile);
	
	/**
	 *	Read the data in.
	 */
	int op;
	std::string word;
	word.reserve(32);
	Trie trie;
	
	while(fin >> op >> word)
	{
		switch(op)
		{
			case 0:
				trie.insert(word);
				break;
			case 1:
				trie.remove(word);
				break;
			case 2:
				fout << trie.getCount(word) << "\n";
				break;
			case 3:
				fout << trie.getLongestPrefixLength(word) << "\n";
				break;
		}
	}
	
	fin.close();	
	fout.close();

	return 0;
}