Table of Contents

Tutorial 3.1 - Set

In acest tutorial, ne propunem sa construim o structura generica Set (multime in sens matematic) capabil sa se redimensioneze automat atunci cand se umple si sa retina numai elemente unice.

GSoC

Google Summer of Code este un program de vară în care studenții (indiferent de anul de studiu) sunt implicați în proiecte Open Source pentru a își dezvolta skill-urile de programare, fiind răsplătiți cu o bursă în valoare totală de 5500$. https://developers.google.com/open-source/gsoc/ UPB se află în top ca număr de studenți acceptați; în fiecare an fiind undeva la aprox. 30-40 de studenți acceptați. Vă încurajăm să aplicați! Există și un grup de fb cu foști participanți unde puteti să îi contactați pentru sfaturi :) https://www.facebook.com/groups/240794072931431/

Pe 14 martie începe perioada de aplicare pentru Google Summer of Code, și aveti la dispoziție 10 zile.

Obiective

Ne dorim:

Dezvoltare

Varianta de bază a clasei Set

Vom folosi std::vector din STL pe post de ResizableArray.

template <class T>
class Set {
	// suportul pe care se salveaza elementele de tip T este un std::vector
	// din STL (Standard Template Library)
	vector <T> array;
};

Constructor default și particular

Pentru a adăuga în Set valorile dintr-un array(pointer) dat ca parametru vom folosi metoda “add” pe care o vom implementa mai jos.

template <class T>
class Set {
	// suportul pe care se salveaza elementele de tip T este un std::vector
	// din STL (Standard Template Library)
	vector <T> array;
 
public:
	Set() {
		// std::vector este deja alocat static,
		// deci nu este nevoie de alocare dinamica
	}
 
	// constructor care initializeaza setul cu valorile unice
	// dintr-un array de elemente de tip T
	Set(T* other, int size) {
		for(int i = 0; i < size; ++i)
			add(other[i]);
	}
 
        // Copy-Constructor
	Set(const Set &other) {
		array = other.array;
		// std::vector are deja implementat assignment operator,
		// asa ca ne vom folosi de el :)
	}
 
	~Set() {
		// std::vector este alocat static, asa ca nu trebuie dealocat
		// dinamic (cu "delete")
	}
};

Adăugare de elemente

înainte de a adăuga un element îl vom căuta în std::vector pentru a fi siguri că este unic.

// adaugarea unui element nou in multime
void add(T element) {
	// il cautam in multime
	for(int i = 0; i < array.size(); ++i)
		// operatorul "==" al clasei T trebuie sa fie "overridden"
		if(array[i] == element)	{
			cout << "Elementul " << element << " exista deja in Set.\n";
			return;
		}
	// daca nu exista deja in Set, il adaugam
	array.push_back(element);
	cout << "Element adaugat cu succes: " << element << "\n";
	// operatorul "<<" al clasei T trebuie sa fie "overridden"
}

Ștergerea elementelor

// stergerea unui element nou in multime
void remove(T element) {
	// il cautam in multime
	for(int i = 0; i < array.size(); ++i)
		// operatorul "==" al clasei T trebuie sa fie "overridden"
		if(array[i] == element)	{
			// daca exista, il stergem folosind metoda "erase" a std::vector
			// iar metoda "begin" returneaza un iterator la inceputul
			// vectorului. more about it later :)
			array.erase(array.begin() + i);
			cout << "Elementul " << element << " a fost sters din Set.\n";
			// operatorul "<<" al clasei T trebuie sa fie "overridden"
			return;
		}		
	// nu avem ce sterge daca nu exista in Set
	cout << "Elementul " << element << " nu exista in Set.\n";
}

Testare și evaluare

Program de test

In continuare vom face un program prin care vom arata folosirea constructorului default si pe cea a celui particular si vom testa metodele de adaugare si de stergere.

#include "Set.h"
 
int main() {
	Set <int> s;
	s.add(1);
	s.add(2);
	s.add(3);
	s.add(3);
 
	s.remove(3);
	s.add(3);
	s.remove(4);
 
	int n;
	cout << "n = ";
	cin >> n;
	int *v = new int[n];
	for(int i = 0; i < n; ++i)
		v[i] = i%5;
 
	Set <int> s2 (v, 7);
	delete[] v;
 
	return 0;
}

Exemplu:

Element adaugat cu succes: 1
Element adaugat cu succes: 2
Element adaugat cu succes: 3
Elementul 3 exista deja in Set.
Elementul 3 a fost sters din Set.
Element adaugat cu succes: 3
Elementul 4 nu exista in Set.
n = 7
Element adaugat cu succes: 0
Element adaugat cu succes: 1
Element adaugat cu succes: 2
Element adaugat cu succes: 3
Element adaugat cu succes: 4
Elementul 0 exista deja in Set.
Elementul 1 exista deja in Set.

Verificare cu Valgrind

Pentru acelasi test rulat cu

 valgrind ./main.out 

toata memoria va fi eliberata.

==11142== HEAP SUMMARY:
==11142==     in use at exit: 0 bytes in 0 blocks
==11142==   total heap usage: 8 allocs, 8 frees, 116 bytes allocated
==11142== 
==11142== All heap blocks were freed -- no leaks are possible
==11142== 
==11142== For counts of detected and suppressed errors, rerun with: -v
==11142== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)