Cod sursa(job #1721737)

Utilizator M.AndreiMuntea Andrei Marius M.Andrei Data 26 iunie 2016 14:10:39
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.62 kb
#ifndef _CRT_NONSTDC_NO_WARNINGS
#define _CRT_NONSTDC_NO_WARNINGS

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
using namespace std;


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



struct Trie {
private:
	int childCount, wordCount;
	Trie* chars[30];


	bool del(Trie* root, const string& word, const int& index);

public:
	Trie() :childCount{ 0 }, wordCount{ 0 } { for (int i = 0; i < 30; i++) chars[i] = nullptr; };
	~Trie() {}
	
	void Adauga(const string& word, Trie** root) {
		if (*root == nullptr) *root = new Trie();
		int size = (int)word.size();
		auto curent = this;

		for (int i = 0; i < size; i++) {
			if (curent->chars[word[i] - 'a'] == nullptr) {
				curent->childCount++;
				Trie* node = new Trie();
				curent->chars[word[i] - 'a'] = node;
				curent = node;
			}
			else curent = curent -> chars[word[i] - 'a'];
		}
		curent->wordCount++;
	}

	int WordCount(const string& word) {
		int size = (int)word.size();
		auto curent = this;

		if (this == nullptr) return 0;
		for (int i = 0; i < size; i++) {
			if (curent->chars[word[i] - 'a'] == nullptr) { return 0; }
			else curent = curent->chars[word[i] - 'a'];
		}
		return curent->wordCount;
	}

	int PrefixCount(const string& word) {
		int size = (int)word.size();
		auto curent = this;
		int prefix = 0;

		if (this == nullptr) return 0;
		for (int i = 0; i < size; i++) {
			if (curent->chars[word[i] - 'a'] == nullptr) break;
			else curent = curent->chars[word[i] - 'a'];
			prefix++;
		}
		return prefix;
	}

	void Sterge(const string& word) {
		del(this, word, 0);
	}

};

Trie* head = new Trie();

bool Trie::del(Trie* root, const string& word, const int& index) {
	int size = (int)word.size();

	if (index == size) {
		root->wordCount--;
		return (root->wordCount == 0 && root->childCount == 0);
	}

	bool delCurent = del(root->chars[word[index] - 'a'], word, index + 1);
	if (delCurent) {
		root->chars[word[index] - 'a'] = nullptr;
		root->childCount--;
	}
	if (root->childCount == 0 && root->wordCount == 0 && root != head) {
		delete(root);
		root = nullptr;
		return true;
	}
	return false;
}


int main() {

	int code;
	string word;
	
	
	while (!fin.eof()) {
		code = -1;
		fin >> code >> word;
		if (code == 0)head->Adauga(word, &head);
		else if (code == 1) head->Sterge(word);
		else if (code == 2)fout << head->WordCount(word) << "\n";
		else fout << head->PrefixCount(word) << "\n";
	}

	delete(head);
	fin.close();
	fout.close();
	return EXIT_SUCCESS;
}



#endif //_CRT_NONSTDC_NO_WARNINGS