Cod sursa(job #2230870)

Utilizator TrixerAdrian Dinu Trixer Data 11 august 2018 23:58:45
Problema Trie Scor 30
Compilator c Status done
Runda Arhiva educationala Marime 2.5 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLEN 21
#define TRIESZ 26

struct trie_node {
	int count;
	int children;
	struct trie_node *child[TRIESZ];
};

struct trie_node *new_trie_node()
{
	struct trie_node *p = malloc(sizeof(struct trie_node));
	p->count = 0;
	p->children = 0;
	for (int i = 0; i < TRIESZ; i++)
		p->child[i] = NULL;
	return p;
}

void delete_trie(struct trie_node *p)
{
	if (p == NULL)
		return;

	for (int i = 0; i < TRIESZ; i++)
		delete_trie(p->child[i]);

	free(p);
}

void add_word_helper(struct trie_node *p, char *s, int len, int level)
{
	if (level == len) {
		p->count++;
		return;
	}

	int idx = s[level] - 'a';
	if (p->child[idx] == NULL) {
		p->child[idx] = new_trie_node();
		p->children++;
	}

	add_word_helper(p->child[idx], s, len, level + 1);
}

void add_word(struct trie_node *p, char *s, int len)
{
	add_word_helper(p, s, len, 0);
}

void delete_word_helper(struct trie_node *p, char *s, int len, int level)
{
	if (level == len) {
		p->count--;
		return;
	}

	int idx = s[level] - 'a';
	if (level == len - 1 &&
		p->child[idx]->children == 0 &&
		p->child[idx]->count == 1) {
		free(p->child[idx]);
		p->child[idx] = NULL;
		return;
	}

	delete_word_helper(p->child[idx], s, len, level + 1);
}

void delete_word(struct trie_node *p, char *s, int len)
{
	delete_word_helper(p, s, len, 0);
}

int get_count_helper(struct trie_node *p, char *s, int len, int level)
{
	if (p == NULL)
		return 0;

	if (level == len)
		return p->count;

	int idx = s[level] - 'a';
	return get_count_helper(p->child[idx], s, len, level + 1);
}

int get_count(struct trie_node *p, char *s, int len)
{
	return get_count_helper(p, s, len, 0);
}

int get_prefix_len_helper(struct trie_node *p, char *s, int len, int level)
{
	if (p == NULL)
		return level - 1;

	int idx = s[level] - 'a';
	return get_prefix_len_helper(p->child[idx], s, len, level + 1);
}

int get_prefix_len(struct trie_node *p, char *s, int len)
{
	return get_prefix_len_helper(p, s, len, 0);
}

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

	// do operations
	int op, len, ret;
	char word[MAXLEN];
	struct trie_node *p = new_trie_node();

	while (scanf("%d%s", &op, word) == 2) {
		len = strlen(word);

		switch (op) {
		case 0:
			add_word(p, word, len);
			break;
		case 1:
			delete_word(p, word, len);
			break;
		case 2:
			ret = get_count(p, word, len);
			printf("%d\n", ret);
			break;
		case 3:
			ret = get_prefix_len(p, word, len);
			printf("%d\n", ret);
			break;
		}
	}

	delete_trie(p);

	return 0;
}