Skip to Content

Dictionare (TTree) in C++

Aceasta este o implementare mai putin eficienta a dictionarelor in C++.
Daca lucrati cu stringuri in JAVA sau PHP aveti ocazia sa vedeti cam cum functioneaza mecanismul lor interior.

demo.cpp

// demo.cpp
#include <iostream>
#include "TTree.h"

using namespace std;

void main()
{
	TTree tree;
	char buf[512];
	char opt;
	do
	{
		cout<<"V - face dictionarul vid\n";
		cout<<"A - adauga un cuvant\n";
		cout<<"S - suprima un cuvant\n";
		cout<<"C - verifica apartenenta unui cuvant\n";
		cout<<"L - listeaza cuvintele\n";
		cout<<"D - afiseaza toate cuvintele ce incep cu o litera data\n";
		cout<<"N - afiseaza numarul de cuvinte, primul si ultimul cuvant din dictionar si cuvintele de lungime minima si maxima\n";
		cout<<"X - terminare\n";
		cout<<"optiunea: ";
		cin>>opt;
		switch(opt)
		{
		case 'v':
			tree.sterge();
			break;
		case 'a':
			cout<<"cuvant: "; cin>>buf;
			tree.adauga(buf);
			break;
		case 's':
			cout<<"cuvant: "; cin>>buf;
			tree.sterge(buf);
			break;
		case 'c':
			cout<<"cuvant: "; cin>>buf;
			if(tree.cauta(buf))
				cout<<"cuvantul a fost gasit\n";
			else
				cout<<"cuvantul nu a fost gasit\n";
			break;
		case 'l':
			tree.afiseaza();
			break;
		case 'd':
			cout<<"litera: "; cin>>buf[0];
			tree.afiseaza(buf[0]);
			break;
		case 'n':
			tree.info();
			break;
		case 'x':
			break;
		default:
			cout<<"optiunea nu exista !\n";
		}
		cout<<endl;
	}
	while(opt != 'x');
}

TTree.h

// TTree.h
#pragma once

#include <iostream>

using namespace std;

const int N = 27;

class Nod
{
public:
	Nod* noduri[N];

	char caracter(int index) {
		if(index < N - 1)
			return 'a' + index;
		else
			return '#';
	}

	bool esteSfarsit() {
		return noduri[N-1] != NULL;
	}

	void puneSfarsit() {
		noduri[N-1] = this;
	}

	int nrUrmasi() {
		int s = 0;
		for(int i=0; i<N; i++)
			if(noduri[i])
				s++;
		return s;
	}

	Nod* urm(int index) {
		return noduri[index];
	}

	Nod* urm(char val) {
		int index;
		if(val >= 'a' && val <= 'z')
			index = val - 'a';
		else
			index = N-1;
		return noduri[index];
	}

	int index(char val) {
		int index;
		if(val >= 'a' && val <= 'z')
			index = val - 'a';
		else
			index = N-1;
		return index;
	}

	Nod() {
		for(int i=0; i<N; i++)
			noduri[i] = NULL;
	}

	~Nod() {
		for(int i=0; i<N-1; i++)
			if(noduri[i])
				delete noduri[i];
	}
};

class TTree
{
private:
	Nod *rad;
	char max[512], min[512];
	int lmin, lmax;

private:
	bool adauga(Nod*& rad, char *val);
	bool cauta(Nod* rad, char *val);
	bool sterge(Nod* rad, char *val);

	void parcurge(Nod* rad, char *buffer, int poz);

public:
	TTree(void);
	~TTree(void);

	void afiseaza()                                    { min[0]='z'+1; max[0]='a'-1; min[1]=max[1]= '\0'; char buf[512]; parcurge(rad, buf, 0); }
	void afiseaza(char start)                          { min[0]='z'+1; max[0]='a'-1; min[1]=max[1]= '\0'; char buf[512]; buf[0] = start; parcurge(rad->urm(start), buf, 1);	}
	void info();

	bool cauta(char *val)                              { return cauta(rad, val);	}
	bool adauga(char *val)                             { return adauga(rad, val);	}
	void sterge(char *val)                             { sterge(rad, val); lmin = 512; lmax = -1;	}
	void sterge()                                      { if(rad) { delete rad; rad = new Nod(); } lmin = 512; lmax = -1;	}
};

TTree.cpp

// TTree.cpp
#include "TTree.h"

TTree::TTree(void)
{
	rad = new Nod();
	lmax = -1;
	lmin = 512;
	min[0] = 'z'+1;
	max[0] = 'a'-1;
	min[1] = max[1] = '\0';
}

TTree::~TTree(void)
{
	sterge();
}

bool TTree::adauga(Nod *&rad, char *val)
{
	if(!rad)
		//	nu exista inca nici un nod in arbore
		rad = new Nod();
	if(val[0] == '\0')
	{
		rad->puneSfarsit();
		return true;
	}
	else
	{
		//	cautam prima litera
		int index = rad->index(val[0]);
		//	adaugam litera urmatoare
		return adauga(rad->noduri[index], val+1);
	}
}

bool TTree::sterge(Nod *rad, char *val)
{
	if(!rad)
		return false;
	if(val[0] == '\0')
	{
		rad->noduri[N-1] = NULL;
		return true;
	}

	int index = rad->index(val[0]);
	Nod *urm = rad->noduri[index];
	if(sterge(urm, val+1))
	{
		//	se poate sa trebuiasca sa stergem urm
		if(urm->nrUrmasi() == 0)
		{
			//	stergem nodul
			delete urm;
			rad->noduri[index] = NULL;
		}
		return true;
	}
	return false;
}

bool TTree::cauta(Nod *rad, char *val)
{
	if(rad == NULL)
		return false;
	if(val[0] == '\0')
	{
		if(rad->esteSfarsit())
			return true;
		else
			return false;
	}
	return cauta(rad->urm(val[0]), val+1);
}

void TTree::parcurge(Nod *rad, char *buffer, int poz)
{
	int i;
	if(rad==NULL)
		return;
	for(i=0; i<N-1; i++)
	{
		buffer[poz] = rad->caracter(i);
		buffer[poz+1] = '\0';
		parcurge(rad->noduri[i], buffer, poz+1);
		buffer[poz] = '\0';
	}
	if(rad->esteSfarsit())
	{
		if(lmin > poz)
			lmin = poz;
		if(lmax < poz)
			lmax = poz;
		if(strcmp(min, buffer) > 0)
			strcpy(min, buffer);
		if(strcmp(max, buffer) < 0)
			strcpy(max, buffer);
		cout<<buffer<<endl;
	}
}

void TTree::info()
{
	if(lmax <= 0)
		afiseaza();
	cout<<"\nlungime maxima: "<<lmax;
	cout<<"\nlungime minima: "<<lmin;
	cout<<"\ncuvant max: "<<max;
	cout<<"\ncuvant min: "<<min;
	cout<<endl;
}