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.
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.
Ne dorim:
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; };
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") } };
î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" }
// 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"; }
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.
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)