Cod sursa(job #541074)

Utilizator feelshiftFeelshift feelshift Data 24 februarie 2011 20:01:55
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
// http://infoarena.ro/problema/trie
#include <fstream>
using namespace std;

#define maxLetters 26
#define maxSize 22
#define character (*word - 'a')

ifstream in("trie.in");
ofstream out("trie.out");

struct trie {
	int counter;
	int sons;

	trie *son[maxLetters];

	trie() {
		counter = sons = 0;
		memset(son,0,sizeof(son));
	}
};

char currentWord[maxSize];
trie *root = new trie;

void insert(trie *node,char *word);
bool erase(trie *node,char *word);
int query(trie *node,char *word);
int prefix(trie *node,char *word,int length);

int main() {
	int type;

	for(;;) {
		in >> type >> currentWord;

		if(in.eof())
			break;

		switch(type) {
			case 0: { insert(root,currentWord); break; }
			case 1: { erase(root,currentWord); break; }
			case 2: { out << query(root,currentWord) << "\n"; break; }
			case 3: { out << prefix(root,currentWord,0) << "\n"; break; }
		}
	}

	in.close();
	out.close();

	return (0);
}

void insert(trie *node,char *word) {
	// daca s-a ajust la finalul cuvantului
	if(*word == 0) {
		// creste numarul de aparitii al cuvantului
		node->counter++;
		return;
	}

	// daca nu are fii
	if(!node->son[character]) {
		// cream unul
		node->son[character] = new trie;

		// crestem numarul de fii ai nodului curent
		node->sons++;
	}

	// inseram urmatoarea litera
	insert(node->son[character],word+1);
}

bool erase(trie *node,char *word) {
	// daca s-a ajuns la finalul cuvantului
	if(*word == 0)
		// scade numarul de aparitii al cuvantului
		node->counter--;
	else
		// daca cuvantul nu mai exista
		// (s-a sters singura sa aparitie)
		if( erase(node->son[character],word+1) ) {
			node->son[character] = 0;
			node->sons--;
		}

	// daca nu mai exista alte aparitii ale 
	// cuvantului (acesta este ultima)
	if(!node->counter && !node->sons && node != root) {
		// se sterge cuvantul
		delete node;

		return true;
	}
	
	// 
	return false;
}

int query(trie *node,char *word) {
	if(*word == 0)
		return node->counter;

	if(node->son[character])
		return query(node->son[character],word+1);
	
	return (0);
}

int prefix(trie *node,char *word,int length) {
	if(*word == 0 || !node->son[character])
		return length;
	else
		return prefix(node->son[character],word+1,length+1);
}