Cod sursa(job #1414691)

Utilizator RengelBotocan Bogdan Rengel Data 2 aprilie 2015 21:36:06
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.46 kb
#include <iostream>
#include <string>

using namespace std;

// defines
#define LETTERS_NO 26

// structs
typedef struct _trie_node
{
	// fields
	int words_end_here;
	int words_via_here;
	_trie_node* next[26];

	struct _trie_node()
	{
		this->words_end_here = 0;
		this->words_via_here = 0;

		for (int i = 0; i < LETTERS_NO; i++)
		{
			(this->next)[i] = NULL;
		}
	}
} trie_node;

// globals
trie_node* root;

// prototypes
void trie_insert(string word);
void trie_erase(string word);
void trie_erase_subtree(trie_node* node);
int	 trie_number_of_occurrences(string word);
int	 trie_length_of_longest_prefix(string word);

int main()
{
	freopen("trie.in", "r", stdin);
	freopen("trie.out", "w", stdout);
	root = new trie_node();

	int operation_type;
	string word;
	while (cin.eof() == false)
	{
		cin >> operation_type >> word;

		switch (operation_type)
		{
		case 0:
			trie_insert(word);
			break;
		case 1:
			trie_erase(word);
			break;
		case 2:
			cout << trie_number_of_occurrences(word) << '\n';
			break;
		case 3:
			cout << trie_length_of_longest_prefix(word) << '\n';
			break;
		default:
			break;
		}
	}

	return 0;
}

void trie_insert(string word)
{
	trie_node* current = root;
	int size = word.size();
	for (int i = 0; i < size; i++)
	{
		current->words_via_here += 1;

		int letters_index = word[i] - 'a';

		// verify if it does not exist an edge corresponding current's letter
		if (current->next[letters_index] == NULL)
		{
			(current->next)[letters_index] = new trie_node();
		}

		current = (current->next)[letters_index];
	}

	current->words_via_here += 1;
	current->words_end_here += 1;
}
void trie_erase(string word)
{
	trie_node* current = root;
	trie_node* ante_current = NULL;
	int letters_index;

	int size = word.size();
	for (int i = 0; i < size; i++)
	{
		current->words_via_here -= 1;
		if (current->words_via_here == 0)
		{
			trie_erase_subtree(current);
			ante_current->next[letters_index] = NULL;
			return;
		}

		letters_index = word[i] - 'a';
		
		if (current->next[letters_index] == NULL)
		{
			return;
		}

		ante_current = current;
		current = (current->next)[letters_index];
	}

	current->words_via_here -= 1;
	if (current->words_via_here == 0)
	{
		trie_erase_subtree(current);
		ante_current->next[letters_index] = NULL;
		return;
	}
	current->words_end_here -= 1;
}
void trie_erase_subtree(trie_node* node)
{
	for (int i = 0; i < LETTERS_NO; i++)
	{
		if (node->next[i] != NULL)
		{
			trie_erase_subtree(node->next[i]);
			node->next[i] = NULL;
		}
	}
	delete(node);
}
int	trie_number_of_occurrences(string word)
{
	trie_node* current = root;
	int size = word.size();
	for (int i = 0; i < size; i++)
	{
		int letters_index = word[i] - 'a';

		// verify if it does not exist an edge corresponding current's letter
		if (current->next[letters_index] == NULL)
		{
			return 0;
		}

		current = (current->next)[letters_index];
	}

	return current->words_end_here;
}
int trie_length_of_longest_prefix(string word)
{
	trie_node* current = root;
	int size = word.size();
	int longest_prefix = 0;
	for (int i = 0; i < size; i++)
	{
		int letters_index = word[i] - 'a';

		// verify if it does not exist an edge corresponding current's letter
		if (current->next[letters_index] == NULL)
		{
			return longest_prefix;
		}

		current = (current->next)[letters_index];
		longest_prefix += 1;
	}

	return longest_prefix;
}