Standard Template Library

Transcript

Standard Template Library
STL - Standard Template Library C++
STL identifica la libreria dei template standard che contiene un insieme di algoritmi e
di strutture di dati di uso comune nella programmazione C++
“Template” indica che la libreria è costituita da classi e funzioni parametrizzate
(template di classi e funzioni)
Fondamenti di Informatica II
26. Standard Template Library STL
STL fa parte dello standard ANSI/ISO del C++
programmare tramite STL si indica con il termine programmazione generica Æ ossia
significa disporre di strutture di dati e algoritmi che possono essere utilizzati in
diversi contesti di elaborazione
Corso di Laurea in Ingegneria Informatica
A.A. 2008-2009
2° Semestre – Corso (A-M)
Prof. Giovanni Pascoschi
2
La Standard Template Library
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Il contenitore vector
vector è un contenitore sequenziale dal comportamento simile agli array, ma con
capacità di espansione automatica e dotata di numerosi metodi per gestire i dati
presenti nel contenitore, che facilitano il programmatore
La Standard Template Library (STL) comprende tre tipologie di componenti:
¾Contenitori
¾Iteratori
¾Algoritmi
l'aggiunta e la rimozione di elementi è rapida solo in coda ed e più lenta nelle altre
posizioni (poichè gli elementi sono immagazzinati in aree di memoria contigue)
I contenitori sono strutture dati come vettori, liste , pile, code e mappe, implementati
con il meccanismo dei template, in grado di memorizzare oggetti di qualsiasi tipo
occorre includere la libreria <vector>:
#include <vector>
Gli iteratori sono puntatori utilizzati per accedere e manipolare gli oggetti memorizzati
nei contenitori in maniera semplificata
la dichiarazione avviene ad esempio con:
vector<int> v; // array di nome v e formato da numeri interi
Gli algoritmi comprendono funzioni d’utilità per il conteggio, l’ordinamento, la ricerca,
ed altre operazioni standard sui contenitori.
oppure
const int MAX = 100;
vector<int> v(MAX); // si passa il parametro MAX al costruttore della classe vector
3
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
4
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Il contenitore vector
Esempio di contenitore vector
Principali metodi
size_type size( );
// restituisce il numero di elementi presenti nel vettore
bool empty( );
// restituisce true se il vettore è vuoto
void push_back(const T& x);// appende x alla fine del vettore
void pop_back( );
// rimuove l’ultimo elemento del vettore
void clear( );
// rimuove tutti gli elementi nel vettore
T& at(size_type i);
// restituisce un riferimento all’elemento in posizione i
#include <vector>
#include <iostream>
using namespace std;
int main( ) {
vector<int> a;
// crea un array di interi a tramite il contenitore vector
for (int i = 1; i <= 5; i++) {
a.push_back(i); // appende il valore i in fondo ad a
}
for (int i = 0; i < a.size( ); i++) {
cout << a[i] << " ";
}
cout << endl;
system("pause");
}
Operatori
I contenitori possono essere confrontati utilizzando gli operatori ==, !=, <=, >=, <, >, e
possono essere assegnati utilizzando l’operatore =. L’operatore [ ] può essere usato
nel vector per accedere ai singoli elementi (in alternativa ad at)
N.B.: size_type Æ Unsigned integral type e corrisponde al tipo intero ritornato
dall’operatore sizeof (esso esprime la dimensione o il numero di byte di ciascun
elemento)
5
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
12345
6
Iteratori
vector<int>::iterator i;
// definisce un iteratore i ad un vettore di interi
i++
// avanza di un elemento
i-// retrocede di un elemento
*i
// restituisce l’oggetto puntato da i
vector<int>::const_iterator i;
// definisce un iteratore i ad un vettore const di
interi (i dati puntati dall’iteratore non possono
essere cambiati)
gli iteratori permettono di accedere a una determinata posizione all’interno del
contenitore per poter agire su quel particolare elemento del contenitore
sintassi:
contenitore<T>::iterator nome;
Metodi di vector che restituiscono o fanno uso di iteratori:
iterator begin( );
// restituisce un iteratore al primo elemento del vettore
iterator end( );
/* restituisce un iteratore che punta subito dopo l’ultimo
elemento del vettore*/
iterator insert(iterator i, const T& x); /* inserisce x nella posizione precedente a quella
puntata dall’iteratore i; restituisce un iteratore
all’elemento inserito */
iterator erase(iterator i); /* cancella l’elemento nella posizione dell’iteratore;
restituisce un iteratore all’elemento successivo a quello
cancellato */
esempio:
vector<int>::iterator i;
tramite l’algebra dei puntatori è possibile accedere a tutti gli elementi del contenitore
vector
esistono due particolari metodi che permettono di individuare l’inizio e la fine del
contenitore:
¾begin( ) Æ restituisce un iteratore che punta al primo elemento del contenitore
¾end ( ) Æ restituisce un iteratore che punta all’ultimo elemento del contenitore
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Iteratori per il contenitore vector
gli iteratori sono una generalizzazione dei puntatori e possono essere applicati con le
stesse modalità ai diversi contenitori
7
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
8
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Scansione degli elementi di vector tramite iteratore
Iteratori costanti
void s2(const vector<int> &v) {
vector<int>::const_iterator it = v.begin( );
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> a;
for (int i = 1; i <= 5; i++) {
a.push_back(i);
}
vector<int>::iterator it;
for (it = a.begin( ); it != a.end( ); it++) {
cout << *it << " ";
}
cout << endl;
system("pause");
}
while (it != v.end( )) {
#include <vector>
cout << *it << " ";
#include <iostream>
it++;
using namespace std;
}
void s1(vector<int> &v) {
cout << endl;
vector<int>::iterator it = v.begin( );
while (it != v.end()) {
cout << *it << " ";
}
int main( ) {
vector<int> a;
it++;
for (int i = 1; i <= 5; i++) a.push_back(i);
}
s1(a);
cout << endl;
s2(a);
}
system("pause");
}
12345
9
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
10
Vector di oggetti
class Persona {
public:
string nome;
int eta;
Persona(string n, int v) {
nome = n; eta = v;
}
};
double media(const vector<Persona> &v)
{
double n = 0;
int d = 0;
vector<Persona>::const_iterator it;
it = v.begin( );
while (it != v.end( )) {
int eta = (*it).eta;
11
Fondamenti di Informatica II – A.A. 2008-2009
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Il contenitore list
n += eta;
d++;
it++;
}
return n/d;
}
int main( ) {
vector<Persona> v;
Persona e1(“antonio",21);
Persona e2(“giovanni",25);
Persona e3(“mario",28);
v.push_back(e1);
v.push_back(e2);
v.push_back(e3);
double m = media(v);
cout << "media = " << m << endl;
system("pause");
}
a cura di Pascoschi Giovanni
list è un contenitore sequenziale che permette inserimenti e cancellazioni rapidi, ma
non permette l'accesso diretto agli elementi se si conosce il numero in sequenza (gli
elementi non sono immagazzinati in aree di memoria contigue)
il contenitore list implementa una struttura di dati organizzata come una lista linkata
doppia (i dati nella lista sono di tipo omogeneo)
occorre includere la libreria <list>:
#include <list>
la dichiarazione avviene ad esempio con:
list<int> l; // lista di nome l e formato da numeri interi
12
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Il contenitore list
Il contenitore list
altri metodi del contenitore list
Metodi principali del contenitore list
size_type size( );
// restituisce il numero di elementi presenti nella lista
bool empty( );
// restituisce true se la lista è vuota
void sort( );
/*ordina gli elementi della lista in ordine crescente usando
l’operatore < associato al tipo degli elementi */
void remove(const T& x);
/*rimuove l’elemento x dalla lista usando l’operatore
== associato al tipo degli elementi */
void push_back(const T& x); // appende x alla fine della lista
13
void push_front(const T& x); // inserisce x all’inizio della lista
Iteratori
void pop_back( );
// rimuove l’ultimo elemento della lista
list<int>::iterator i;
// definisce un iteratore i ad una lista di interi
void pop_front( );
// rimuove il primo elemento della lista
i++
// avanza di un elemento
void clear( );
// rimuove tutti gli elementi nella lista
i--
// retrocede di un elemento
void reverse( );
// inverte la lista
*i
// restituisce l’oggetto puntato da i
void merge( );
// effettua la fusione di due liste (già ordinate)
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
14
Il contenitore list
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Esempio di contenitore list
#include <list>
Metodi di list che restituiscono o fanno uso di iteratori:
#include <iostream>
iterator begin( ); // restituisce un iteratore al primo elemento della lista
using namespace std;
iterator end( ); /* restituisce un iteratore che punta subito dopo l’ultimo elemento della
lista*/
void eliminanumPari(list<int> &l) {
void visualizza(const list<int> &l) {
list<int>::const_iterator it;
for(it = l.begin( ); it != l.end( ); it++)
cout << *it << " ";
cout << endl;
list<int>::iterator it;
iterator insert(iterator i, const T& x); /* inserisce x nella posizione precedente a quella
puntata dall’iteratore i; restituisce un iteratore
all’elemento inserito*/
it = l.begin();
while (it != l.end()) {
}
int main( ) {
list<int> l;
int val = *it;
iterator erase(iterator i); /* cancella l’elemento nella posizione dell’iteratore;
for (int i = 1; i <= 20; i++)
if (val % 2 == 0) it = l.erase(it);
restituisce un iteratore all’elemento successivo a quello
cancellato*/
l.push_back(i);
else it++;
eliminanumPari(l);
}
visualizza(l);
}
system("pause");
}
1 3 5 7 9 11 13 15 17 19
15
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
16
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Confronto tra vector e list
Il contenitore map
map è un array associativo, che permette di associare elementi (valori) a chiavi di
vario tipo (simile agli array paralleli)Æ i valori sono mappati (indicizzati) tramite le
chiavi di ricerca
chiave1
valore1
vector è organizzato in memoria centrale come un insieme di elementi contigui Æ
l‘accesso diretto al singolo elemento è piu’ veloce, ma fare nuovi inserimenti e
cancellazioni è piu’ lento
list non richiede memoria allocata in modo contiguo Æ non consente accesso
diretto ma sequenziale, ma fare nuovi inserimenti e cancellazioni è molto piu’
efficiente Æ richiede piu’ memoria perchè devono essere gestiti due puntatori per
ciascun dato
chiave2
valore2
...
...
chiave n
valore n
il tipo delle chiavi puo’ essere diverso dal tipo dei valori Æ la struttura viene
mantenuta ordinata in funzione dell’ordine crescente del valore delle chiavi
in definitiva è piu’ conveniente usare vector quando non bisogna fare frequenti
inserimenti/cancellazioni e si vuole accedere in maniera diretta a un elemento
occorre includere la libreria <map:
#include <map>
è piu’ conveniente usare list quando non bisogna accedere in maniera diretta agli
elementi ed occorre fare numerosi interventi di inserimento o eliminazioni
la dichiarazione avviene ad esempio con:
map<int, string> libro; //mappa dei libri a cui si accede tramite un intero (p.e. codice)
libro[cod] = “Il milione”;
17
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
18
Il contenitore map
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Il contenitore map
Metodi principali
size_type size( )
Iteratori
// restituisce il numero di elementi nella mappa m
bool empty( )
// restituisce true se la mappa m è vuota
void insert(valType(“antonio", 22)) // inserisce nella mappa il valore 22 con chiave
“antonio"; l’inserimento avviene soltanto se nella
mappa non esiste già un’istanza con la stessa chiave
iterator find(“antonio")
// restituisce un iteratore all’istanza nella mappa la cui
chiave è “antonio”; se l’istanza non è presente
restituisce un iteratore uguale a end( )
int count(“antonio")
// restituisce il numero di istanze nella mappa la cui
chiave è “antonio"; il valore restituito può essere 0 o 1
map<string,int>::iterator i;
// un iteratore ad una mappa <string,int>
i++
// avanza di un elemento
i--
// retrocede di un elemento
(*i).first
// restituisce la chiave dell’oggetto puntato da i (oppure->)
(*i).second
// restituisce il valore dell’oggetto puntato da i (oppure->)
Metodi di map che restituiscono o fanno uso di iteratori:
iterator begin( ); // restituisce un iteratore al primo elemento della mappa
iterator end( ); // restituisce un iteratore che punta subito dopo l’ultimo elemento della
mappa
typedef map<string,int>::value_type valType; // definisce val come tipo associato a map
iterator erase(iterator i); // cancella l’elemento nella posizione dell’iteratore; restituisce un
iteratore all’elemento successivo a quello cancellato
19
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
20
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Esempio di contenitore map
Uso dell’operatore [ ] per inserire valori in una mappa
#include <map>
#include <iostream>
using namespace std;
}
#include <map>
#include <iostream>
using namespace std;
int main( ) {
map<string,int> m;
m[“Antonio"] = 21;
m[“Mario"] = 24;
m["Giovanni"] = 21";
map<string,string>::iterator it;
for(it = m.begin( ); it != m.end( ); it++)
cout << it->first << ": " << it->second << endl;
system("pause");
}
Antonio : 23
Antonio : 23
Mario: 24
Mario: 24
int main( ) {
map<string,int> m;
typedef map<string,int>::value_type val; // definisce val come tipo associato a map
m.insert(val(“Antonio", 23));
m.insert(val(“Mario", 24));
m.insert(val("Giovanni", 21));
map<string,int>::iterator it;
for(it = m.begin( ); it != m.end( ); it++)
cout << it->first << ": " << it->second << endl;
system("pause");
Giovanni: 21
Giovanni: 21
21
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
22
Altri contenitori STL (coda/pila)
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Contenitore string
std::queue
#include <queue>
"Container Adapter" (contenitore basato su altri contenitori) ottimizzato per il
funzionamento in modo FIFO (First In, First Out) con push( ) = inserzione in testa e
pop( ) = rimozione in coda.
string è una classe della libreria STL che rappresenta un caso particolare di
contenitore costituito da un array di caratteri
std::stack
#include <stack>
"Container Adapter" (contenitore basato su altri contenitori) ottimizzato per il
funzionamento in modo LIFO (Last In, First Out) con push( ) = inserzione e pop( ) =
rimozione in testa.
la dichiarazione avviene ad esempio con:
string nome; // stringa con nome “nome”
23
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
occorre includere la libreria <string>:
#include <string>
definisce al suo interno l’overloading degli operatori:
¾ = assegnazione
¾ == confronto
¾ + concatenazione
¾ << output su stream
¾ >> per l’input da stream
24
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Il contenitore string
Algoritmi STL
Metodi principali
string::substr(indice, numero) restituisce una stringa costituita dalla sottostringa a
partire dalla posizione indice con numero di caratteri
string::size( ) restituisce il numero di caratteri (escluso \0)
Il vantaggio principale della libreria STL è la possibilità di utilizzare una vasta
collezione di algoritmi (procedure standard applicate a strutture dati standard). Di
seguito verranno analizzati solo alcuni degli algoritmi disponibili nella libreria
standard C++, ai quali si può accedere attraverso gli header file <algorithm> e
<numeric>.
string::replace(indice,numero,stringa) sostituisce una stringa con un’altra a partire
dalla posizione indice da numero di caratteri e stringa rimpiazzata
string::c_str( )
converte un tipo string in un array di caratteri char* per rendere il codice compatibile
con le librerie della gestione delle stringhe in C (p.e. nome.c_str( ) e poi bisogna usare
le tipiche funzioni del C strcpy, etc)
25
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
26
Algoritmi STL
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Algoritmi STL
#include <algorithm>
Algoritmi principali:
iterator find(iterator first, iterator last, const T& value);
Gli elementi nell’intervallo [first,last] sono confrontati con value usando l’operatore ==
associato al tipo T. Se si trova una corrispondenza, la ricerca finisce e restituisce un
iteratore all’elemento. Se non trova alcuna corrispondenza viene restituito last.
void replace(iterator first, iterator last, const T& oldVal, const T& newVal)
Sostituisce tutte le istanze di oldVal con newVal nell’intervallo specificato dalla coppia di
iteratori [first,last)
void sort(iterator first, iterator last)
Riordina gli elementi nell’intervallo [first,last] in ordine crescente usando l’operatore <
associato al tipo degli elementi.
27
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
conta(iterator first1, iterator last1, val_cercato)
conta gli elementi che sono uguali a val_cercato
max_element( ) e min_element( )
esempio:
vector<int> v;
vector<int>::iterator i;
........
i=max_element(v.begin( ), v.end( ));
cout<< “massimo: “<< *i << endl;
i=min_element(v.begin( ), v.end( ));
cout<<“minimo: “<< *i<<endl;
........
28
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Esempio sull’uso dell’algoritmo find
Funzioni virtuali (ulteriori chiarimenti)
#include <list>
triangolo_rett
#include <algorithm>
#include <iostream>
base
altezza
using namespace std;
int main( ) {
Assegna
Area
Perimetro
Stampa
list<int> l;
for (int i = 1; i <= 10; i++) l.push_back(i);
int x;
cout << "Numero da cercare: ";
triangolo_isosc
class triangolo_rett {
public:
double base, altezza;
void Assegna(double, double);
double Area( );
double Perimetro( );
void Stampa( ):
triangolo_rett( ): base(0.0),altezza(0.0) { }
};
cin >> x;
list<int>::iterator it = find(l.begin( ), l.end( ), x);
if (it != l.end( )) cout << "Numero trovato\n";
else cout << "Numero non trovato\n";
Perimetro
system("pause");
}
29
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
30
Funzioni virtuali (ulteriori chiarimenti)
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Funzioni virtuali (ulteriori chiarimenti)
void triangolo_rett::Assegna(double b, double h) {
base=b;
altezza=h;
}
class triangolo_isosc:public triangolo_rett {
public:
double Perimetro( );
};
double triangolo_rett::Area( ) {
return base*altezza/2;
}
void triangolo_isosc::Perimetro( ) {
return base+2*sqrt(pow(altezza,2.0)+pow(base/2,2.0));
}
double triangolo_rett::Perimetro( ) {
return (base+altezza+sqrt(pow(base,2.0),pow(altezza,2.0)));
}
void triangolo_rett::Stampa( ) {
cout << base << endl;
cout << altezza << endl;
cout<< Area( ) << endl;
cout<< Perimetro( ) << endl;
}
31
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
32
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Funzioni virtuali (ulteriori chiarimenti)
Funzioni virtuali (ulteriori chiarimenti)
#include <iostream>
#include <cmath>
int main( ) {
triangolo_rett TR;
triangolo_isosc TI;
TR.Assegna(2.0, 3.0);
TI.Assegna(5.0, 4.0);
TR.Stampa( );
TI.Stampa( ); //risultato errato perchè viene richiamato il metodo della classe base
}
33
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
class triangolo_rett {
public:
double base, altezza;
void Assegna(double, double);
double Area( );
virtual double Perimetro( );
void Stampa( ):
triangolo_rett( ): base(0.0),altezza(0.0) { }
};
34
Riepilogo della lezione
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Fine della lezione
STL - Standard Template Library C++
Contenitori (vector, list, map, string)
Iteratori
Algoritmi (find, sort, ecc)
Ulteriori chiarimenti sulle funzioni virtuali
35
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Domande?
36
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni
Esercizi 1-2
Implementare la classe della pila con i metodi richiesti nelle lezioni
precedenti utilizzando il contenitore vector
Implementare la classe della pila con i metodi richiesti nelle lezioni
precedenti utilizzando il contenitore list
37
Fondamenti di Informatica II – A.A. 2008-2009
a cura di Pascoschi Giovanni