Cod sursa(job #815341)

Utilizator moscaliuc_ovidiuMoscaliuc Ovidiu moscaliuc_ovidiu Data 16 noiembrie 2012 21:11:22
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 4.33 kb
#include <fstream>
#include <map>
#include <string.h>
#include <assert.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 && !children.size() && pParent)
				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() && !count)
			{
				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 
			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);
	}
};

#define CH (*s - 'a')


	
	using namespace std;


	
struct Trie {
	
		int cnt, nrfii;
	
		Trie *fiu[ 26 ];
	

		
		Trie() {
			
				cnt = nrfii = 0;
			
				memset( fiu, 0, sizeof( fiu ) );
			
	}

};


	
	Trie *T = new Trie;


	
	void ins( Trie *nod, char *s ) {
		
			if( *s == '\n' ) {
				
					nod->cnt ++; return;
				
			}
			

			
				if( nod->fiu[ CH ] == 0 ) {
					
						nod->fiu[ CH ] = new Trie;
					
						nod->nrfii ++;
					
				}
				

					
					ins( nod->fiu[ CH ], s+1 );
				
}


	
	int del( Trie *nod, char *s ) {
		
			if( *s == '\n' )
				
				nod->cnt --;
		
			else if( del( nod->fiu[ CH ], s+1 ) ) {
				
					nod->fiu[ CH ] = 0;
				
					nod->nrfii --;
				
		}
		

			
			if( nod->cnt == 0 && nod->nrfii == 0 && nod != T ) {
				
					delete nod; return 1;
				
			}
			
				return 0;
			
}


	
	int que( Trie *nod, char *s ) {
		
			if( *s == '\n' )
				
				return nod->cnt;
		

			
			if( nod->fiu[ CH ] )
				
				return que( nod->fiu[ CH ], s+1 );
		
			return 0;
		
}


	
	int pre( Trie *nod, char *s, int k ) {
		
			if( *s == '\n' || nod->fiu[ CH ] == 0 )
			
				return k;
		
			return pre( nod->fiu[ CH ], s+1, k+1 );
		
}

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

	Tree tree;

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

		fin>>op;
		fin>>w;

		switch(op)
		{
		case 0:
			tree.addWord(w);
			ins(T, w);
			break;
		case 1:
			tree.deleteWord(w);
			del(T, w);
			break;
		case 2:
			//fout<<tree.count(w)<<'\n';
			fout<<que(T, w)<<'\n';
			break;
		case 3:
			//fout<<tree.maxPrefixLength(w)<<'\n';
			fout<<pre(T, w)<<'\n';
			break;
		default:
			break;
		}
	}

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

	return 0;
}