Cod sursa(job #754227)

Utilizator mika17Mihai Alex Ionescu mika17 Data 1 iunie 2012 04:43:54
Problema Trie Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <cassert>
#include <cstring>
#include <string>
#include <fstream>
using namespace std;

class Trie
{
private:
	class Node
	{
		int count, prefs;
		Node *sons[26], *parent;
		Node()
		{
			count = prefs = 0;
			memset(sons,0,sizeof(sons));
			parent = 0;
		}
		friend class Trie;
	} *root;

	inline int getSon(char c) { return c - 'a'; }
public:

	Trie() : root(new Node) {}
	void add(const string& s)
	{
		root->prefs ++;
		Node * r = root;
		for(string::const_iterator i = s.begin(); i != s.end(); r = r->sons[getSon(*i++)])
		{
			if(!r->sons[getSon(*i)])
			{
				Node *q = r->sons[getSon(*i)] = new Node();
				q->parent = r;
			}
			r->sons[getSon(*i)]->prefs ++;
		}
		r->count ++;
	}
	void remove(const string& s)
	{
		
		Node * r = root;
		for(string::const_iterator i = s.begin(); r && i != s.end(); r = r->sons[getSon(*i++)]);
		
		if(!r || r->count == 0)
			return;
		r->count --;
		for(string::const_iterator i = s.end() - 1; i != s.begin(); --i)
		{
			Node *q = r;
			r->prefs --;
			r = r->parent;
			if(q->prefs == 0)
				delete q, r->sons[getSon(*i)] = 0;
		}
	}
	int count(const string& s)
	{
		Node * r = root;
		for(string::const_iterator i = s.begin(); r && i != s.end(); r = r->sons[getSon(*i++)]);
		return r == NULL ? 0 : r->count;
	}
	int longestPrefix(const string& s)
	{
		int l = 0;
		Node * r = root;
		for(string::const_iterator i = s.begin(); i != s.end(); ++i)
		{
			 if( (r = r->sons[getSon(*i)]) != NULL ) ++l;
			 else break;
		}
		return l;
	}
	~Trie() { /*assert(root->prefs == 0);*/ delete root; }
};

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

	Trie T;
	
	while(!fin.eof())
	{
		char code; string str; fin >> code >> str;
		if(fin.eof()) break;
		switch(code)
		{
		case '0': T.add(str); break;
		case '1': T.remove(str); break;
		case '2': fout << T.count(str) << '\n'; break;
		case '3': fout << T.longestPrefix(str) << '\n'; break;
		}
	}
}