Sunteți pe pagina 1din 13

Standard Template Library -STL

 bibliotecă de șabloane de clase standard, în principal pentru principalele structuri de


date: vector, lista, stiva, coada, tabela de dispersie (hash-table);
 se pot instanția fara modificări pentru tipurile de bază sau pentru tipurile definite de
programator (vector<double>, list<Pers>, stack<Stud*> etc.)
 sarcina programatorului de a alege șablonul adecvat, în funcție de volumul datelor
stocate, tipul de acces dorit, volumul actualizărilor etc.
Standard Template Library -STL
Structura:
• Containerele – implementează șabloanele principalelor structuri de date

• Iteratorii – generalizează principalele modalități de a accesa un element dintr-un


container

• Algoritmii – implementează principalele operații într-o manieră independentă de


container
Standard Template Library -STL
Containere
Stocheaza obiecte si metodele de acces la ele
• după ordine si acces
• forward
• reversible
• random access

• după organizare
• secvențiale: structuri liniare, acces bazat pe ordine sau pe procedee gestionate de programator
• asociative: stocheaza chei sau asocieri cheie-valoare, precum și metode de acces bazate pe chei
• adaptoare: adapteaza containerele secvențiale, conferindu-le funcționalități de stivă, coadă, coadă cu
priorități
Container secvențial: vector
 folosește spațiu contiguu de memorie dinamică => performanță la acces direct prin
poziție element (index);
 redimensionare cu realocare si posibila mutare; ineficient pentru că se apelează alocator
obiect vector, apel de constructor de copiere pentru fiecare element stocat, apel
destructor elemente din poziția veche, dezalocare obiect vector vechi …
 anticiparea redimensionărilor: Reserve() pentru spațiu suplimentar
 permite atribuire între vectori
 operații eficiente: acces prin index, pop_back()
 operații care depind de context: push_back()
 operații ineficiente: insert / erase la început sau în interior
Container secvențial: vector
vector<Pers> vp(2); vp.reserve(3); // caz probabil: stim aproximativ, 2 sau 3 elemente
Pers p1(20, "Domintan E"), p2(30, "Traistaru V"), p3(40, "Patrulescu I"), p4(50, "Cincinat P");
vp[0]=p1; cout<<"\nNrElemente="<<vp.size()
<<" cu extindere pana la ="<<vp.capacity()<<endl;
vp[1]=p2;
// vp[2]=p3; err depasire capacitate
vp.push_back(p3); // utilizeaza rezervarea!
vp.push_back(p4); // necesita mutare ?! depinde ...
for(int i=0;i<vp.size();i++) cout<<vp[i];
vp[0]=p1; cout<<"\nDupa realocari: size ="<<vp.size()<<" capacity="<<vp.capacity()<<endl;
Container secvențial: vector
vector<Pers*> vpp; // nu dimensionam caci nu stim cate elemente vom tine
vpp.push_back(new Pers(50, "John"));
// adaugam, dar probabil nu muta, caci un element are doar 4 B (pointer)
vpp.push_back(new Pers(60, "Helen")); vpp.push_back(new Pers(70, "Rita"));
vector<Pers*>::iterator iter_pers; // parcurgere cu iterator, ineficienta
for(iter_pers = vpp.begin(); iter_pers != vpp.end(); iter_pers++ ) cout << **iter_pers <<" " ;
//end() pointeaza dupa ultimul element
cout <<endl;
// stergere element din mijloc
iter_pers=vpp.begin()+vpp.size()/2; vpp.erase(iter_pers); cout << *vpp[1];
Container secvențial: vector
// stergere element din mijloc
iter_pers=vpp.begin()+vpp.size()/2; vpp.erase(iter_pers); cout << *vpp[1];

// iterator reverse
vector<Pers*>::reverse_iterator rit;
for(rit= vpp.rbegin(); rit!= vpp.rend(); rit++) cout<<(**rit);
Container secvențial: list
 implementată ca o listă dublu-înlănțuită; previous(); next();
 ocupă o zonă de memorie necontiguă
 eficient: inserări / ștergeri de elemente (nu știm prealabil câte noduri va ține)
 ineficient: căutare element (deplasări și identificare);
 spațiu mai mare de stocare
Container secvențial: list
#include <list>
#include <iostream>
using namespace std;
void main()
{
list<double> ld;
ld.push_back(10.1); ld.push_front(20.2); ld.push_back(30.3);
ld.insert(ld.begin(),50.5); ld.insert(ld.end(),60.6);
double vd[]={123.4,234.5,345.6, 456.7, 567.8};
ld.insert(ld.begin(),vd+1,vd+4); // insert segment din vector clasic
ld.sort();
list<double>::iterator it;
for(it= ld.begin(); it!= ld.end();it++) cout<<(*it)<<" ";
}
Container secvențial: deque
DoubleEndedQueue
 combină facilitățile de la vector și list
 utilizeză blocuri contigui de memorie, gestionate cu vectori de pointeri
 operații specifice: push_front(); pop_front();
 eficient: acces, inserare la început și sfârșit
 ineficient: inserări/ștergeri în interior
 opțiune bună în comparație cu vector când nu se cunoaște apriori numărul de elemente.
 deque în faza de populare, după care containerul este copiat în vector !
 nu dezalocă zonele de memorie deja allocate, ci invalideaza iteratorii deja incarcati
Container secvențial: deque
int n = 10;
deque<int> dq(15);
deque<int>::iterator pd;
dq.push_front(0); // creste size la 16 !
pd = dq.begin()+1;
generate_n( pd, n, Fibonacci ); // populare cu functie generatoare
vector<int> vi(dq.size());
for(pd = dq.begin(); pd != dq.end(); pd++ ) cout << *pd <<" " ;
cout <<endl;
for(int i=0; i<dq.size(); i++) { vi[i]=dq[i]; cout << vi[i] << " "; }
Container asociative: set
Pers p[10]={ Pers(45,"Mateescu Dan"), Pers(25,"Ionescu Tudor") };
set< Pers> echipa_1;
set< Pers, greater<Pers>, allocator<Pers> > echipa_2;
echipa_1.insert(p[1]); echipa_1.insert(p[6]);
cout << "\n"<< p[0].nume << " este " <<
(echipa_1.key_comp()( p[0], p[1]) ?
" mai tinar(a) ": " mai batrin(a) " ) << " decat " << p[1].nume << endl;

set< Pers>::iterator iter_pers;


p[5].varsta=25;
iter_pers = echipa_1.find(p[5]); // iter_pers = echipa_1.find(p[0]);
iter_pers!= echipa_1.end() ?
cout << "\n Gasit: "<< iter_pers->nume : cout << "\n Negasit ! ";
#include <iostream>
Container asociative: map
#include <map> // vector asociativ
#include <string> // definitia clasei string
using namespace std;
typedef pair<string, int> pereche; // key : value
void main()
{
string nume; char aux[50];
map<string, int> agenda; map<string, int>::iterator it;
agenda.insert(pereche("Ionescu F",722123456)); agenda.insert(pereche("Popescu A",744123456)); // construire agenda
while(cout<<"\n Nume sau CTRL/Z:", cin.getline(aux,50) )//cautare in agenda
{
nume=aux; it=agenda.find(nume);
if(it!=agenda.end())
cout<<"\n"<<(*it).first<<" tel: "<<(*it).second; // sau cout<<"\n"<<agenda[nume]; // acces prin cheie
else
cout<<"\n"<<nume<<" nu exista in agenda!!!";
}
for(it=agenda.begin(); it!=agenda.end(); it++) cout<<"\n"<<(*it).first<<" : "<<(*it).second; // afisare continut agenda
}