Cod sursa(job #1361069)

Utilizator anaid96Nasue Diana anaid96 Data 25 februarie 2015 19:27:30
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.78 kb
#include<stdio.h>
#include<string.h>

using namespace std;

FILE *in, *out;

//definitions
#define letter *word - 'a'

//constants
const int sz = 21;
const int alphabet = 26;

//structures
struct trie 
{
	int words;
	int sons;
	
	trie *son[alphabet];
	
	trie () // intialize
	{
		words = sons = 0;
		memset(son, '\0', sizeof(son));
	}
};

//variables
int type;
char currentWord[sz];

trie *root = new trie;

//functions
void addWord( trie *node, char *word);
bool eraseWord( trie *node, char *word);
int query( trie *node, char *word);
int prefix( trie *node, char *word, int lenght=0);

int main(void)
{
	in = fopen("trie.in", "rt");
	out = fopen("trie.out", "wt");

	for(;;)
	{
		
		fscanf(in, "%d", &type);
		fscanf(in, "%s", currentWord);
		if( feof(in))
			break;
		if(type)
		{
			if(type == 1) // sterge currentWord
				eraseWord(root, currentWord);
			else if( type == 2) // print -> numarul de aparitii ale lui currentWord
					fprintf(out, "%d\n",query(root, currentWord));
			else // print -> lungimea celui mai lung prefix comun
				fprintf(out, "%d\n", prefix(root, currentWord));
			
		}
		else // adauga currentWord
			addWord(root, currentWord);
	}
	fclose(in);
	fclose(out);
	return 0;
}


void addWord(trie *node, char *word)
{
	if( !*word) // daca nu mai am litere in word
	{
		node->words++; // cresc numarul de aparitii
		return;
	}
	
	if( !node->son[letter]) // daca fiul letter (*word - 'a') nu exista
	{
		node->sons++; // cresc numarul de fii
		node->son[letter] = new trie; // si adaug fiul letter
	}
	
	addWord(node->son[letter], word+1); // apelez pentru fiul letter si repet pentru word+1
}

bool eraseWord( trie *node, char *word)
{
	if(!*word) // daca nu mai am litere in word
		--node->words; // scad numarul de cuvinte <=> sterg cuvantul
	else
		if(eraseWord(node->son[letter], word+1)) // pana ajung la sfarsitul cuvantului
		{								//daca mai pot sterge noduri
			--node->sons;
			node->son[letter] = '\0';
		}
	if(node == root || node->words || node->sons) //daca nodul este radacina sau nu mai am
		return false;						//cuvin sau fii
	
	delete node;
	return true;
	
}

int query( trie *node, char *word)
{
	if(!*word) //daca nu mai am litere
		return node->words; // inseamna ca am ajuns la sfarsitul cuvantului si returnez
						//numarul de aparitii a cuvantului
	if(node->son[letter]) //daca exista fiul letter
		return query(node->son[letter], word+1); // apelez pentru fiul letter
	
	return 0; // in cazul in care cuvantul word nu apare deloc in structura
}

int prefix( trie *node, char *word, int lenght)
{
	if( !*word || !node->son[letter]) // daca nu mai am litere in word sau nu mai exita fiul letter
		return lenght;
	return prefix(node->son[letter], word+1, lenght+1);
}