Cod sursa(job #1494631)

Utilizator ArkinyStoica Alex Arkiny Data 1 octombrie 2015 17:26:20
Problema Trie Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.39 kb
#include<fstream>

using namespace std;

struct Node
{
	Node *next_l,*next_r;
	char letter;
	int r;
};

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

class Trie
{
	static const int MAX_SIZE = 26;
	Node *tree;
	Node* del[20];
	int l;

	void remove_element(const char *str);

	public:
		Trie() :tree(0),l(0) {};
		void add(const char *str);
		void remove(const char *str);
		int  count(const char *str);
		int  samePrefix(const char*str);

};


void Trie::add(const char *str)
{
	Node *q,*p=0;
	int i;
	q = tree;
	for (i = 0; *(str + i) != '\0';++i)
	{
		if (q == 0)
		{
			q = new Node;
			q->next_l = 0;
			q->next_r = 0;
			q->r = (str[i+1] == '\0');
			q->letter = str[i];

			if (p)
				p->next_r = q;

			if (tree == 0)
				tree = q;
			p = q;
			q = q->next_r;
		}
		else
		{
			while (q->next_l)
			{
				if (q->letter == str[i])
					break;
				q = q->next_l;
			}
			if (q->next_l == 0 && q->letter != str[i])
			{
				q->next_l = new Node;
				q->next_l->next_l = 0;
				q->next_l->next_r = 0;
				q->next_l->r= (str[i + 1] == '\0');
				q->next_l->letter = str[i];

				p = q->next_l;

				q = q->next_l->next_r;
				continue;
			}
			if (str[i + 1] == '\0')
				q->r++;
			q = q->next_r;
		}
	}
}
void Trie::remove_element(const char *str)
{
	--l;
	while (l > 0 && del[l]->next_r == 0)
	{

		if (del[l - 1]->next_r == del[l] && del[l]->letter == str[l])
			del[l - 1]->next_r = del[l]->next_l;
		else
		{
			del[l]->next_l = del[l]->next_l->next_l;
		}
		--l;
	}
	if (l == 0 && del[l]->next_r == 0)
	{
		if (del[l] == tree)
			tree = del[l]->next_l;
		else
			del[l]->next_l = del[l]->next_l->next_l;
	}
	l = 0;
}
void Trie::remove(const char *str)
{
	Node *q = tree;
	for (int i = 0; *(str + i) != '\0';++i)
	{
		if (q && q->letter == str[i])
		{
			del[l++] = q;
			if (str[i + 1] == '\0')
			{
				if (q->r > 1)
				{
					--q->r;
					l = 0;
				}
				else
					remove_element(str);
				return;
			}
			q = q->next_r;
			continue;
		}
		while (q && q->next_l)
		{
			if (q->next_l->letter == str[i])
			{
				del[l++] = q;
				if (str[i + 1] == '\0')
				{
					if (q->r > 1)
						--q->r;
					else
						remove_element(str);
					q = q->next_r;

					break;
				}
				q = q->next_l;
			}
			if (!q)
				return;
		}
	}
}

int Trie::count(const char *str)
{
	Node *q = tree;
	for (int i = 0; *(str + i) != '\0';++i)
	{
		while (q)
		{
			if (q->letter == str[i])
			{
				if (str[i + 1] == '\0')
					return q->r;
				q = q->next_r;
				break;
			}
			q = q->next_l;
		}
		if (!q)
			return 0;
	}
}

int Trie::samePrefix(const char *str)
{
	Node *q = tree;
	int nr = 0;
	for (int i = 0; *(str + i) != '\0';++i)
	{
		while (q)
		{
			if (q->letter == str[i])
			{
				if (str[i + 1] == '\0')
					return nr;
				q = q->next_r;
				++nr;
				break;
			}
			q = q->next_l;
		}
		if (!q)
			return nr;
	}
}

void DFS(Node *p)
{
	while (p)
	{
		out << p->letter << " " << p->r << '\n';
		DFS(p->next_r);
		p = p->next_l;
	}
}

int main()
{
	Trie trie;
	int i;
	char s[20];
	while (in >> i && in >> s)
	{
		switch (i)
		{
		case 0:
			trie.add(s);
			break;
		case 1:
			trie.remove(s);
			break;
		case 2:
			out<<trie.count(s)<<'\n';
			break;
			
		case 3:
			out << trie.samePrefix(s)<<'\n';
			break;
		}
	}
	return 0;
}