Cod sursa(job #2646963)

Utilizator RaduQQTCucuta Radu RaduQQT Data 2 septembrie 2020 15:43:27
Problema Trie Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.47 kb
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//arbore de cuvinte trie

/*
0 w - adauga o aparitie a cuvantului w in lista
1 w - sterge o aparitie a cuvantului w din lista
2 w - tipareste numarul de aparitii ale cuvantului w in lista
3 w - tipareste lungimea celui mai lung prefix comun al lui w cu oricare cuvant din lista
*/


typedef struct trie
{
	trie* prev;
	trie* next[26];
	char letter;
	int noWord;
};

trie* arbore;
trie* createNode(char letter)
{
	trie* node = (trie*)malloc(sizeof(trie));
	node->letter = letter;
	for (int i = 0; i < 26; i++)
		node->next[i] = NULL;
	node->noWord = 0;
	return node;
}

void addWord(char* word)
{
	trie* node = arbore;
	for (int i = 0; i < strlen(word); i++)
	{
		if (node->next[word[i] - 'a'] == NULL)
		{
			node->next[word[i] - 'a'] = createNode(word[i]);
			node->next[word[i] - 'a']->prev = node;
		}
		node = node->next[word[i] - 'a'];
	}
	node->noWord++;
}


trie* findWord(char* word)
{
	trie* node = arbore;
	for (int i = 0; i < strlen(word); i++)
	{
		if (node->next[word[i] - 'a'] != NULL)
			node = node->next[word[i] - 'a'];
		else
			return NULL;
	}
	return node;
}

void erasingWord(trie* node)
{
	while (1)
	{
		if (node->noWord)
			return;
		for (int i = 0; i < 26; i++)
		{
			if (node->next[i] != NULL)
				return;
		}
		trie* garb = node;
		char a = node->letter;
		node = node->prev;
		free(garb);
		node->next[a - 'a']=NULL;
	}
}

bool eraseWord(char* word)
{
	trie* node = findWord(word);
	if (node == NULL || node->noWord == 0)
		return 0;
	else
		node->noWord--;
	if (node->noWord == 0)
	{
		erasingWord(node);
	}
	return 1;
}

int findLCPrefix(char* word)
{
	trie* node = arbore;
	for (int i = 0; i < strlen(word); i++)
	{
		if (node->next[word[i] - 'a'] != NULL)
			node = node->next[word[i] - 'a'];
		else
			return i;
	}
	return strlen(word);
}
int main()
{
	freopen("trie.in", "r", stdin);
	freopen("trie.out", "w", stdout);

	arbore = createNode(' ');
	arbore->prev = NULL;

	int noCerinta;
	char* word=(char*)malloc(50);

	while (scanf("%d%s", &noCerinta, word) != EOF)
	{
		if (noCerinta == 0)
			addWord(word);
		else if (noCerinta == 1)
			eraseWord(word);
		else if (noCerinta == 2)
		{
			trie* node = findWord(word);
			if (node == NULL)
				printf("0\n");
			else
			printf("%d\n", node->noWord);
		}
		else
		{
			printf("%d\n",findLCPrefix(word));
		}
	}
}