Cod sursa(job #1171150)

Utilizator roxana.istratePoenaru Roxana roxana.istrate Data 15 aprilie 2014 11:58:40
Problema Trie Scor 55
Compilator cpp Status done
Runda Arhiva educationala Marime 2.65 kb
#include <fstream>
#include <string>
#include <stdlib.h>

#define max 26
#define MAX 100000

using namespace std;

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

struct Trie{
	int pass; // how many nodes pass through this node 
	int appear;	// how many nodes end here
	struct Trie *refs[max];
};

typedef struct Trie Trie;

Trie root;

void addWord(string word){
	int index = 0, len = word.size();
	Trie *t = &root;
	while(index < len){
		if(t->refs[word[index]-'a'] == NULL){
			Trie *nou = (Trie*)malloc(1*sizeof(Trie));
			nou->pass = 1;
			nou->appear = 0;
			for(int i = 0; i < max; i++)
				nou->refs[i] = NULL;
			t->refs[word[index]-'a'] = nou;
		}else{
			t->refs[word[index]-'a']->pass++;
		}
		
		// sets final node
		if(index == len-1){
			t->refs[word[index]-'a']->appear ++;
		}
		t = t->refs[word[index]-'a'];
		index ++;
	}
}

int printHowMany(string word){
	Trie *t = &root;
	int index = 0, len = word.size();
	while(index < len && t != NULL){
		t = t->refs[word[index]-'a'];
		index ++;
	}
	if(index == len && t != NULL){
		return t->appear;
	}
	return 0;
}

void deleteWord(string word){
	Trie *t = &root, *next;
	int index = 0, len = word.size();
	if(printHowMany(word) == 0) return ;
	while(index < len){
		if(t->refs[word[index]-'a']->pass == 1){
			if(t->refs[word[index]-'a']->appear > 0){
				free(t->refs[word[index]-'a']);
				t->refs[word[index]-'a'] = NULL;
			}else{
				for(int i = 0; i < 26; i++){
					if(t->refs[word[index]-'a']->refs[i] != NULL){
						next = t->refs[word[index]-'a']->refs[i];
						free(t->refs[word[index]-'a']);
						t->refs[word[index]-'a'] = NULL;
						t->refs[i] = next;
						break;
					}
				}
			}
		}else{
			t->refs[word[index]-'a']->pass--;
			if(index == len-1){
				t->refs[word[index]-'a']->appear--;
			}
			t = t->refs[word[index]-'a'];
		}
		index++;
	}
}

int printPrefix(string prefix){
	Trie *t = &root;
	int len = prefix.size(), index = 0, maxim = 0;
	while(index < len){
		if(t->refs[prefix[index] - 'a'] != NULL){
				t = t->refs[prefix[index] - 'a'];
				maxim++;
		}else{
			break;
		}
		index++;
	}
	return maxim;
}

void process(int which, string word){
	switch(which){
	case 0: addWord(word); break;
	case 1: deleteWord(word); break;
	case 2: fout << printHowMany(word) << "\n"; break;
	case 3: fout << printPrefix(word) << "\n";
	}
}

int main(){
	int which, i = 16;
	string word;

	root.appear = 0;
	root.pass = 0;	 // passul asta nu are relevanta pt root 
	for(int i = 0; i < max; i++)
		root.refs[i] = NULL;

	while(fin >> which >> word){
		process(which, word);
		i--;
	}
	return 0;
}