Cod sursa(job #1721677)

Utilizator M.AndreiMuntea Andrei Marius M.Andrei Data 26 iunie 2016 12:50:19
Problema Trie Scor 55
Compilator cpp Status done
Runda Arhiva educationala Marime 2.69 kb
#ifndef _CRT_NONSTDC_NO_WARNINGS
#define _CRT_NONSTDC_NO_WARNINGS

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


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

class TrieNode {
private:
	void destructTrie(TrieNode* root) {
		for (auto item : root->child) {
			auto key = item.first;
			destructTrie((root->child)[key]);
			delete((root->child)[key]);
			(root->child)[key] = nullptr;
		}
		(root->child).erase(root->child.begin(), root->child.end());

	}

	bool del(TrieNode* curent, const string& word, const int& index) {
		
		int size = (int)word.length();

		if (index == size) {
			if (curent->count == 0) return false;
			curent->count--;
			return (curent->count == 0 && curent->child.size() == 0);
		}
		
		auto node = (curent->child)[word[index]];
		bool shouldDeleteCurentNode = del(node, word, index + 1);

		if (shouldDeleteCurentNode) {
			curent->child.erase(word[index]);
			delete (node);
			return (curent->child.size() == 0);
		}
		return false;

	}

	int count;
	map<char, TrieNode*> child;

public:

	TrieNode() :count{ 0 } {};
	~TrieNode() { destructTrie(this); }

	void Adauga(const string& word) {
		
		int size = (int)word.size();
		auto root = this;

		for (int i = 0; i < size; i++) {
			auto it = (root->child).find(word[i]);
			if (it == (root->child).end()) {
				TrieNode* node = new TrieNode();
				(root->child)[word[i]] = node;
				root = node;
			}
			else root = (root->child)[word[i]];
		}
		root->count++;
	}

	int Count(const string& word) {

		int size = (int)word.size();
		auto root = this;

		for (int i = 0; i < size; i++) {
			auto it = (root->child).find(word[i]);
			if (it == (root->child).end()) return 0;
			root = (root->child)[word[i]];
		}
		return root->count;
	}

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

		for (int i = 0; i < size; i++) {
			auto it = (root->child).find(word[i]);
			if (it == (root->child).end()) break;
			root = (root->child)[word[i]];
			prefix++;
		}
		return prefix;
	}

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


int main() {

	TrieNode tr;
	int code;
	string word;

	while (fin >> code >> word) {
		switch (code)
		{
		case 0: tr.Adauga(word);
			break;
		case 1:
			tr.Sterge(word);
			break;
		case 2:
			fout << tr.Count(word)<<"\n";
			break;
		case 3:
			fout << tr.findPrefix(word)<<"\n";
			break;
		default:
			break;
		}
	}

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



#endif //_CRT_NONSTDC_NO_WARNINGS