Cod sursa(job #1595153)

Utilizator creativedoughnutCreative Doughnut creativedoughnut Data 9 februarie 2016 23:23:31
Problema Trie Scor 45
Compilator cpp Status done
Runda Arhiva educationala Marime 3.26 kb
#define _CRT_SECURE_NO_WARNINGS

#include <fstream>
#include <vector>
#include <string>

#define TRIE_NUMBER_OF_CHILDREN_PER_NODE 26

using namespace std;

class Node
{
public:		// variables
	Node* childrens[TRIE_NUMBER_OF_CHILDREN_PER_NODE];
	int value = 0;

public:		// methods
	Node()
	{
		for (int i = 0; i < TRIE_NUMBER_OF_CHILDREN_PER_NODE; i++)
		{
			this->childrens[i] = NULL;
		}
	}
	
	~Node()
	{
		for (int i = 0; i < TRIE_NUMBER_OF_CHILDREN_PER_NODE; i++)
		{
			if (this->childrens[i] == NULL)
			{
				continue;
			}
			delete(this->childrens[i]);
		}
	}
};

class Trie
{
public:		// methods
	void AddWord(string word)
	{
		Node* current = root;
		for (string::iterator it = word.begin(); it != word.end(); it++)
		{
			char c = *it;
			int index = c - 'a';

			if (current->childrens[index] == NULL)
			{
				current->childrens[index] = new Node();
			}
			current = current->childrens[index];
		}

		current->value += 1;
	}

	void RemoveWord(string word)
	{
		Node* current = root;
		Node* fromNodeToDelete = NULL;
		int indexToDelete = -1;
		
		for (string::iterator it = word.begin(); it != word.end(); it++)
		{
			char c = *it;
			int index = c - 'a';

			if (current->childrens[index] == NULL)
			{
				return;
			}

			if (current->childrens[index]->value == 0 && fromNodeToDelete == NULL)
			{
				fromNodeToDelete = current;
				indexToDelete = index;
			}

			string::iterator it2 = it;
			it2++;

			if(current->childrens[index]->value != 0 && it2 != word.end())
			{
				fromNodeToDelete = NULL;
			}

			current = current->childrens[index];
		}

		current->value -= 1;

		if (current->value == 0 && fromNodeToDelete != NULL)
		{
			// we should delete something
			delete(fromNodeToDelete->childrens[indexToDelete]);
			fromNodeToDelete->childrens[indexToDelete] = NULL;
		}
	}

	int GetNumberOfOccurences(string word)
	{
		Node* current = root;
		for (string::iterator it = word.begin(); it != word.end(); it++)
		{
			char c = *it;
			int index = c - 'a';

			if (current->childrens[index] == NULL)
			{
				return 0;
			}
			current = current->childrens[index];
		}

		return current->value;
	}

	int GetLongestPrefix(string word)
	{
		Node* current = root;
		int longestPrefix = 0;
		for (string::iterator it = word.begin(); it != word.end(); it++)
		{
			char c = *it;
			int index = c - 'a';

			if (current->childrens[index] == NULL)
			{
				return longestPrefix;
			}

			longestPrefix += 1;
			current = current->childrens[index];
		}

		return longestPrefix;
	}

	~Trie()
	{
		delete(root);
	}

private:	// variables
	Node* root = new Node();

private:	// methods

};

int main()
{
	ifstream input("trie.in");
	ofstream output("trie.out");
	
	int option;
	string word;
	Trie trie;
	int occurences;
	int prefixLength;

	while (input >> option >> word)
	{
		switch (option)
		{
		case 0:
			trie.AddWord(word);
			break;
		case 1:
			trie.RemoveWord(word);
			break;
		case 2:
			occurences = trie.GetNumberOfOccurences(word);
			output << occurences << '\n';
			break;
		case 3:
			prefixLength = trie.GetLongestPrefix(word);
			output << prefixLength << '\n';
			break;
		default:
			break;
		}
	}

	return 0;
}