Cod sursa(job #1308200)

Utilizator whoasdas dasdas who Data 3 ianuarie 2015 19:16:42
Problema Trie Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 kb
#define IA_PROB "trie"


#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>

#include <algorithm>

#include <fstream>
#include <iostream>

using namespace std;

class Trie {
private:
	const char eow = 'z' + 1;

	struct node {
		int refcnt;
		unordered_map<char, node*> children;
		node() : refcnt(0), children() { }
	} root;

public:
	void insert(string &word) {
		node *n = &root;
		n->refcnt++;
		word.push_back(eow);
		for (char c : word) {
			auto it = n->children.find(c);
			if (it == n->children.end()) {
				node *nn = new node();
				n->children[c] = nn;
				n = nn;
			} else {
				n = it->second;
			}
			n->refcnt++;
		}
	}
	void remove(string &word) {
		/* we're assuming that word is definitely present;
		 * otherwise we'd first have to look it up. */
		word.push_back(eow);
		int l = 0;
		node *prev = NULL, *cur = &root, *next = root.children[word[l]];
		while (next) {
			prev = cur;
			cur = next;
			next = ++l < word.size() ? cur->children[word[l]] : NULL;

			cur->refcnt--;
			if (cur->refcnt == 0) {
				if (prev) {
					prev->children.erase(word[l - 1]);
				}
				delete cur;
				cur = NULL;
			}
		}



	}
	int count(string &word) {
		node *n = &root;
		word.push_back(eow);
		for (char c : word) {
			auto it = n->children.find(c);
			if (it == n->children.end()) {
				return 0;
			}
			n = it->second;
		}
		return n->refcnt;
	}
	int max_common_prefix_len(string &word) {
		int ret = 0;
		node *n = &root;
		for (char c : word) {
			auto it = n->children.find(c);
			if (it == n->children.end()) {
				break;
			}
			n = it->second;
			ret++;
		}
		return ret;
	}
};

int main()
{
	freopen( IA_PROB".in", "r", stdin );
	freopen( IA_PROB".out", "w", stdout );

	Trie trie;

	char line[ 32 ];
	fgets( line, 32, stdin );

	string word;
	word.reserve(32);

	while( !feof( stdin ) ) {
		word = line + 2;
		word.pop_back();
		switch( line[0] ) {
			case '0': trie.insert(word); break;
			case '1': trie.remove(word); break;
			case '2': printf( "%d\n", trie.count(word) ); break;
			case '3': printf( "%d\n", trie.max_common_prefix_len(word) ); break;
		}

		fgets( line, 32, stdin );
	}
	return 0;
}