Cod sursa(job #868383)

Utilizator sana1987Laurentiu Dascalu sana1987 Data 30 ianuarie 2013 22:43:30
Problema Trie Scor 45
Compilator c Status done
Runda Arhiva educationala Marime 2.52 kb
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define N              ('z' - 'a' + 1)
#define BUFFER_SIZE               1024

typedef struct trie_node_ {
	int key;
	int prefixes;
	struct trie_node_ *children[N];
} trie_node;


void trie_add(trie_node *root, char *word) {
	root->prefixes++;
	if (!*word) {
		root->key++;
		//printf("[add] %p %d\n", root, root->key);
		return;
	}

	int pos = *word - 'a';
	if (!root->children[pos]) {
		root->children[pos] = (trie_node *) malloc(sizeof(trie_node));
		memset(root->children[pos], 0, sizeof(trie_node));
	}
	trie_add(root->children[pos], word + 1);
}

void trie_remove(trie_node *root, char *word) {
	root->prefixes--;
	if (!*word) {
		if (root->key > 0)
			root->key--;
		//printf("[remove] %p %d\n", root, root->key);
		return;
	}

	int pos = *word - 'a';
	if (!root->children[pos])
		return;

	trie_remove(root->children[pos], word + 1);
}

int trie_count(trie_node *root, char *word) {
	if (!*word) return root->key;

	int pos = *word - 'a';
	if (!root->children[pos]) return 0;
	return trie_count(root->children[pos], word + 1);
}

int trie_prefix(trie_node *root, char *word) {
	if (root->prefixes == 0)
		return 0;

	if (!word)
		return 0;

	int pos = *word - 'a';
	if (!root->children[pos]) return 0;
	int tmp = trie_prefix(root->children[pos], word + 1);
	if (tmp == 0 && root->children[pos]->prefixes > 0)
		tmp = 1;
	else if (tmp > 0)
		tmp++;
	return tmp;
}

void debug(trie_node *root, char *word) {
	printf("%p |%s| %d\n", root, word, root->prefixes);
	if (!*word)
		return;
	int pos = *word - 'a';
	if (!root->children[pos]) return;
	debug(root->children[pos], word + 1);
}

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

    static char line[BUFFER_SIZE];
    memset(line, 0, BUFFER_SIZE);

    static trie_node root;
    memset(&root, 0, sizeof(trie_node));

    while (1) {
    	fgets(line, BUFFER_SIZE, stdin);
    	if (feof(stdin)) break;
    	int len = strlen(line);
    	line[len - 1] = 0;
    	if (len <= 1) {
    		break;
    	}

    	char *word = line + 2;

    	if (line[0] == '0') {
    		//printf("ADD |%s|\n", word);
    		trie_add(&root, word);
    	}
    	else if (line[0] == '1') {
    		//printf("REMOVE |%s|\n", word);
    		trie_remove(&root, word);
    	}
    	else if (line[0] == '2') {
    		int tmp = trie_count(&root, word);
    		printf("%d\n", tmp);
    	}
    	else if (line[0] == '3') {
    		//debug(&root, word);
    		int tmp = trie_prefix(&root, word);
    		printf("%d\n", tmp);
    	}
    }

    return 0;
}