Cod sursa(job #1947942)

Utilizator k.bruenDan Cojocaru k.bruen Data 31 martie 2017 15:31:53
Problema Trie Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb
#include <fstream>
#include <string>
using std::string;

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

class trie {
	class nod {
	public:
		int aparitii;
		nod * copii[26];

		nod() {
			this->aparitii = 0;
			for (int i = 0; i < 26; i++) copii[i] = NULL;
		}
	} *radacina = new nod;

	void adauga(nod*& pozitie, string deAdaugat) {
		if (deAdaugat.length() == 0) {
			pozitie->aparitii++;
			return;
		}
		char curent = deAdaugat[0];
		if (pozitie->copii[curent - 'a'] == NULL) {
			pozitie->copii[curent - 'a'] = new nod;
		}
		return adauga(pozitie->copii[curent - 'a'], deAdaugat.substr(1));
	}

	void sterge(nod*& pozitie, string deSters) {
		if (deSters.length() != 0) sterge(pozitie->copii[deSters[0] - 'a'], deSters.substr(1));
		else {
			pozitie->aparitii--;
			return;
		}

		if (pozitie->copii[deSters[0] - 'a']->aparitii != 0) return;

		char curent = deSters[0];

		bool allEmpty = true;

		for (int i = 0; i < 26 && allEmpty; i++) if (pozitie->copii[curent - 'a']->copii[i] != NULL) allEmpty = false;

		if (allEmpty) {
			delete pozitie->copii[curent - 'a'];
			pozitie->copii[curent - 'a'] = NULL;
		}
	}

	int aparitii(nod*& pozitie, string deCautat) {
		if (deCautat.length() == 0) return pozitie->aparitii;

		if (pozitie->copii[deCautat[0] - 'a'] == NULL) return 0;

		return aparitii(pozitie->copii[deCautat[0] - 'a'], deCautat.substr(1));
	}

	int prefix(nod*& pozitie, string dePotrivit, int adancime = 0) {
		if (dePotrivit.length() == 0) return adancime;

		//int copii = 0;
		//int urmator = -1;
		//for (int i = 0; i < 26; i++) if (pozitie->copii[i] != NULL) { copii++; urmator = i; }

		//if (urmator != dePotrivit[0] - 'a') return adancime;

		//if (copii == 1) return prefix(pozitie->copii[urmator], dePotrivit.substr(1), adancime + 1);
		//else return adancime;

		if (pozitie->copii[dePotrivit[0] - 'a'] == NULL) return adancime;
		else return prefix(pozitie->copii[dePotrivit[0] - 'a'], dePotrivit.substr(1), adancime + 1);
	}

public:
	void Adauga(string deAdaugat) { adauga(radacina, deAdaugat); }
	void Sterge(string deSters) { sterge(radacina, deSters); }
	int Aparitii(string deCautat) { return aparitii(radacina, deCautat); }
	int CelMaiLungPrefix(string dePotrivit) { return prefix(radacina, dePotrivit); }
} Trie;

string cuvant;

int main() {
	while (!in.eof()) {
		int comanda = -1;
		in >> comanda >> cuvant;

		switch (comanda) {
		case 0:
			Trie.Adauga(cuvant);
			break;
		case 1:
			Trie.Sterge(cuvant);
			break;
		case 2:
			out << Trie.Aparitii(cuvant) << '\n';
			break;
		case 3:
			out << Trie.CelMaiLungPrefix(cuvant) << '\n';
			break;
		default:
			return 0;
		}
	}

	return 0;
}