Cod sursa(job #811211)

Utilizator moscaliuc_ovidiuMoscaliuc Ovidiu moscaliuc_ovidiu Data 11 noiembrie 2012 18:11:46
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.97 kb
#include <fstream>
#include <map>
#include <string.h>

class TrieNode
{
private:
	typedef std::map<char, TrieNode*>		Children;

private:
	TrieNode		*pParent;
	Children	children;
	char		ch;
	int			count;

public:
	TrieNode() : pParent(0), ch('\0'), count(0)
	{

	}

	TrieNode(TrieNode *_pParent, char _ch) : pParent(_pParent), ch(_ch), count(0)
	{

	}

	void processWord(const char *_pszWord)
	{
		if (strlen(_pszWord))
		{
			Children::iterator	itNode;

			itNode = children.find(_pszWord[0]);
			if (children.end() != itNode)
				itNode->second->processWord(_pszWord + 1);
			else
			{
				TrieNode *pNode = new TrieNode(this, _pszWord[0]);
				
				children.insert(std::make_pair(_pszWord[0], pNode));				

				pNode->processWord(_pszWord + 1);
			}
		}
		else
			count ++;
	}

	void deleteWord(const char *_pszWord)
	{
		if (strlen(_pszWord))
		{
			Children::iterator	itNode;

			itNode = children.find(_pszWord[0]);
			if (children.end() != itNode)
				itNode->second->deleteWord(_pszWord + 1);
		}
		else
		{
			count --;
			if (!count)
				pParent->deleteChild(this->ch);
		}
	}

	void deleteChild(char _ch)
	{
		Children::iterator	itNode;

		itNode = children.find(_ch);
		if (children.end() != itNode)
			children.erase(itNode);

		if (!children.size())
		{
			if (pParent)
				pParent->deleteChild(ch);
		}
	}

	int getCount(const char *_pszWord)
	{
		if (strlen(_pszWord))
		{
			Children::iterator	itNode;

			itNode = children.find(_pszWord[0]);
			if (children.end() != itNode)
				return itNode->second->getCount(_pszWord + 1);
			else
				return 0;
		}
		else if (children.size())
			return 0;
		else
			return count;
	}

	int maxPrefixLength(const char *_pszWord, int _h)
	{
		if (strlen(_pszWord))
		{
			Children::iterator	itNode;

			itNode = children.find(_pszWord[0]);
			if (children.end() != itNode)
				return itNode->second->maxPrefixLength(_pszWord + 1, _h + 1);
			else
				return _h;
		}
		else
			return _h;
	}

	bool operator < (const TrieNode &_other)
	{
		return ch < _other.ch;
	}
};

class Tree
{
private:
	TrieNode		root;

public:
	Tree()
	{

	}

	void addWord(const char *_pszWord)
	{
		root.processWord(_pszWord);
	}

	void deleteWord(const char *_pszWord)
	{
		root.deleteWord(_pszWord);
	}

	int count(const char *_pszWord)
	{
		return root.getCount(_pszWord);
	}

	int maxPrefixLength(const char *_pszWord)
	{
		return root.maxPrefixLength(_pszWord, 0);
	}
};

int main()
{
	std::ifstream fin("trie.in");
	std::ofstream fout("trie.out");

	Tree tree;

	while(!fin.eof())
	{
		char	w[21];
		int op;

		fin>>op;
		fin>>w;

		switch(op)
		{
		case 0:
			tree.addWord(w);
			break;
		case 1:
			tree.deleteWord(w);
			break;
		case 2:
			fout<<tree.count(w)<<std::endl;
			break;
		case 3:
			fout<<tree.maxPrefixLength(w)<<std::endl;
			break;
		default:
			break;
		}
	}

	fin.close();
	fout.close();

	return 0;
}