Cod sursa(job #1227192)

Utilizator SeekHunt1334Septimiu Bodica SeekHunt1334 Data 9 septembrie 2014 17:28:11
Problema Trie Scor 5
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
using namespace std;

ifstream fin("trie.in");
ofstream fout("trie.out");

struct Node {
	int words;
	int prefixes;
	Node *edges[27];
	
	Node() : words(0), prefixes(0) {
		for (unsigned int i = 0; i < 26; ++i)
			edges[i] = NULL;
	}
	
	Node(const Node& a) { *this = a; }
	~Node() 
	{
		for (unsigned int i = 0; i < 26; ++i)
			if ( edges[i] ) delete edges[i];
	}
} root;

void Read();
void AddWord(Node&, string word);
void RemoveWord(Node&, string word);
int CountWords(Node&, string word);
int LongestCommonPrefix(Node&, string word, int depth);




void DebugPrintGraph(Node& node);
void DebugWriteChanges();


int main()
{
	Read();
	
	fin.close();
	fout.close();
	return 0;
}

int LongestCommonPrefix(Node& node, string word, int depth)
{
	if ( !word.empty() ) 
	{
		char k = word[0];
		word.erase(0, 1);
		if ( node.edges[k-'a'] != NULL ) 
			return LongestCommonPrefix(*node.edges[k-'a'], word, depth+1);

	}
	return depth;
}

int CountWords(Node& node, string word)
{
	if ( word.empty() ) return node.words;
	char k = word[0];
	if ( node.edges[k - 'a'] == NULL ) return 0;
	word.erase(0, 1);
	return CountWords(*node.edges[k-'a'], word);
}

void RemoveWord(Node& node, string word)
{
	if ( !word.empty() )
	{
		char k = word[0];
		word.erase(0, 1);

		if ( node.edges[k-'a'] != NULL )
		{
			RemoveWord(*node.edges[k-'a'], word);
			if ( node.edges[k-'a']->prefixes <= 1 )
			{
				if ( node.edges[k-'a']->words  > 1 ) 
					node.edges[k-'a']->words--;
				else
				{
					delete node.edges[k-'a'];
					node.edges[k-'a'] = NULL;
				}
			}
			else
			if ( node.edges[k-'a']->words >= 1 )
				node.edges[k-'a']->words--;
		}
	}
}

void AddWord(Node& node, string word)
{
	if ( word.empty() )
		node.words++;
	else
	{
		node.prefixes++;
		char k = word[0];
		if ( node.edges[k - 'a'] == NULL ) 
			node.edges[k - 'a'] = new Node();
		word.erase(0, 1); // erases first character
		AddWord(*node.edges[k - 'a'], word);
	}
}

void Read()
{
	int type; string word;
	while ( fin >> type >> word )
	{
		//DebugWriteChanges();
  
		
		if ( type == 0 )
			AddWord(root, word);
		if ( type == 1 )
			RemoveWord(root, word);
		if ( type == 2 ) fout << 
			CountWords(root, word) << '\n';
		if ( type == 3 ) fout << 
			LongestCommonPrefix(root, word, 0) << '\n';
			
		
		//DebugWriteChanges();
		
	}
	fout << '\n';
}

void DebugWriteChanges()
{
		for (unsigned int i = 0; i < 5; ++i)
			fout << "***BEGIN***" << ' ';
		fout << '\n';
		
		DebugPrintGraph(root);

		
		for (unsigned int i = 0; i < 5; ++i)
			fout << "***END***" << ' ';
		fout << '\n';	
}

void DebugPrintGraph(Node& node)
{
	static unsigned int depth = 1;
	fout << "Step: " << depth++ << '\n';
	
	fout << "words: " << node.words << ' ' 
		 << "prefixes: " << node.prefixes << ' '
		 << "edges: ";
	for (unsigned int i = 0; i < 26; ++i)
		if ( node.edges[i] ) 
			fout << char(i + 'a') << ' ';
	fout << '\n';			
	
	for (unsigned int i = 0; i < 26; ++i)
		if ( node.edges[i] )
			DebugPrintGraph(*node.edges[i]);
}