Cod sursa(job #1753386)

Utilizator dtoniucDaniel Toniuc dtoniuc Data 6 septembrie 2016 14:09:28
Problema Trie Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.81 kb
#include <fstream>
#include <cstring>

using namespace std;

typedef struct elem
{
	int val;
	int depth;
	int wordNumber;
	struct elem** childList;
public:
	elem(int val, int depth)
		{this->val = val; this->depth = depth; childList = new elem*[27](); wordNumber = 0;}

	~elem() {delete[] childList; childList = NULL;}
}Elem;

void Insert(int pos, int length, char word[], Elem* root);
void Delete(int pos, int length, char word[], Elem** root);
int FindWordNumber(int pos, int length, char word[], Elem* root);
int FindPrefixLength(int pos, int length, char word[], Elem* root);
void DeleteElem(Elem** root);

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

    int opt;
    char word[21];
    Elem* root = new Elem(-1, 0);

    while(fin >> opt >> word)
    {
    	switch(opt)
    	{
    		case 0:
    			Insert(0, strlen(word), word, root);
    			break;
    		case 1:
    			Delete(0, strlen(word), word, &root);
    			break;
    		case 2:
				fout << FindWordNumber(0, strlen(word), word, root) << "\n";
    			break;
    		case 3:
    			fout << FindPrefixLength(0, strlen(word), word, root) << "\n";
    			break;
    		default:
    			exit(1);
    	}
    }

    fin.close();
    fout.close();
    return 0;
}

void Insert(int pos, int length, char word[], Elem* root)
{
	if (pos > length - 1)
	{
		root->wordNumber ++;
	}
	else
	{
		if(root->childList[word[pos] - 'a'] == NULL)
		{
			root->childList[word[pos] - 'a'] = new Elem(word[pos] - 'a', root->depth + 1);
		}

		Insert(pos + 1, length, word, root->childList[word[pos] - 'a']);
	}
}

void Delete(int pos, int length, char word[], Elem** root)
{
	if (pos <= length - 1)
	{
		if((*root)->childList[word[pos] - 'a'] == NULL)
		{
			return;
		}
		Delete(pos + 1, length, word, &((*root)->childList[word[pos] - 'a']));
	}
	else
	{
		(*root)->wordNumber--;
	}

	DeleteElem(root);
}

void DeleteElem(Elem** root)
{
	if(root == NULL)
		return;

	if((*root)->wordNumber == 0)
	{
		bool flag = true;

		for(int i = 0; i < 26; i++)
		{
			if((*root)->childList[i] != NULL)
				flag = false;
		}

		if(flag)
		{
			delete (*root);
			(*root) = NULL;
		}
	}
}

int FindWordNumber(int pos, int length, char word[], Elem* root)
{
	if(root == NULL)
	{
		return 0;
	}

	if (pos == length)
	{
		return root->wordNumber;
	}
	else
	{
		return FindWordNumber(pos + 1, length, word, root->childList[word[pos] - 'a']);
	}
}

int FindPrefixLength(int pos, int length, char word[], Elem* root)
{
	if(root == NULL || pos > length)
	{
		return 0;
	}

	int result = 0;
	if (pos < length)
		result = FindPrefixLength(pos + 1, length, word, root->childList[word[pos] - 'a']);

	if(result != 0)
		return result;

	bool flag = false;

	for(int i = 0; i < 26; i++)
	{
		if(root->childList[i] != NULL)
			flag = true;
	}

	if(flag || root->wordNumber > 0)
		return root->depth;

	return 0;
}