Cod sursa(job #868409)

Utilizator sana1987Laurentiu Dascalu sana1987 Data 30 ianuarie 2013 23:20:44
Problema Trie Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.28 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++;
		return;
	}

	//printf("[add] %p %d\n", root, root->prefixes);
	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) {
	if (!*word) {
		if (root->key > 0) {
			root->key--;
			root->prefixes--;
		}
		return;
	}

	root->prefixes--;
	//printf("[remove] %p %d\n", root, root->prefixes);
	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, int nr) {
	//printf("%s ||| %p %d %d\n", word, root, root->key, root->prefixes);
	if (root->prefixes <= 0)
		return nr - 1;
	if (!*word || !root->children[*word - 'a'])
		return nr;
	return trie_prefix(root->children[*word - 'a'], word + 1, nr + 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') {
    		int tmp = trie_prefix(&root, word, 0);
    		printf("%d\n", tmp);
    	}
    }

    return 0;
}