Cod sursa(job #943465)

Utilizator howsiweiHow Si Wei howsiwei Data 25 aprilie 2013 16:20:10
Problema Trie Scor 45
Compilator cpp Status done
Runda Arhiva educationala Marime 1.9 kb
#include <fstream>
#include <vector>
using namespace std;
#define ech(it, A) for (typeof(A.begin()) it = A.begin(); it != A.end(); ++it)

class Trie {
public:
	Trie() {
		root = new Node();
	}

	void insert( string s ) {
		Node * t = root;
		ech(it, s) {
			++t->cnt_prefix;
			if (t->child[*it-'a'] == NULL) {
				t->child[*it-'a'] = new Node;
			}
			t = t->child[*it-'a'];
		}
		++t->cnt_prefix;
		++t->cnt_end;
	}

	void remove( string s ) { // s must be in trie 
		Node ** t = &root;
		ech(it, s) {
			--(*t)->cnt_prefix;
			if ((*t)->cnt_prefix == 0 && *t != root) {
				Node ** tmp = &((*t)->child[*it-'a']);
				delete *t;
				*t= NULL;
				t = tmp;
			}
			else t = &((*t)->child[*it-'a']);
		}
		--(*t)->cnt_prefix;
		--(*t)->cnt_end;
		if ((*t)->cnt_prefix == 0) {
			delete *t;
			*t = NULL;
		}
	}

	int count( string s ) {
		Node * t = root;
		ech(it, s) {
			if (t->child[*it-'a'] == NULL) return 0;
			t = t->child[*it-'a'];
		}
		return t->cnt_end;
	}

	int countPre( string s ) {
		Node * t = root;
		ech(it, s) {
			if (t->child[*it-'a'] == NULL) return 0;
			t = t->child[*it-'a'];
		}
		return t->cnt_prefix;
	}

	int lenMatchPre( string s ) {
		Node * t = root;
		int len = 0;
		ech(it, s) {
			if (t->child[*it-'a'] == NULL) return len;
			t = t->child[*it-'a'];
			++len;
		}
		return len;
	}

private:
	struct Node {
		Node() {
			child.resize(26);
			cnt_prefix = 0;
			cnt_end = 0;
		}
		vector<Node *> child;
		int cnt_prefix;
		int cnt_end;
	};

	Node * root;
};

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

	Trie dict;
	short op;
	string s;
	
	while (fin >> op) {
		fin >> s;
		switch (op) {
			case 0: dict.insert(s); break;
			case 1: dict.remove(s); break;
			case 2: fout << dict.count(s) << '\n'; break;
			case 3: fout << dict.lenMatchPre(s) << '\n'; break;
		}
	}

	return 0;
}