La Standard Template Library Heap, algoritmi e funtori

annuncio pubblicitario
La Standard Template Library
Heap, algoritmi e funtori
Pericle Perazzo
27 maggio 2011
Algoritmi e strutture dati
La Standard Template Library del C++
Riassunto contenitori e iteratori
Un contenitore è un oggetto che contiene un insieme di altri oggetti di tipo omogeneo
(=gli elementi del contenitore).
Un iteratore è un oggetto che punta ad un elemento di un contenitore.
1
Algoritmi e strutture dati
La Standard Template Library del C++
Riassunto contenitori e iteratori
vector<int>
set<int>
deque<int>
map<string, int>
list<int>
2
Algoritmi e strutture dati
La Standard Template Library del C++
Riassunto contenitori e iteratori
Gli iteratori possono essere usati per visitare o fare operazioni più complesse sui
contenitori.
list < int > l ;
/∗ . . . ∗/
list < int >:: iterator i ;
for ( i = l . begin (); i != l . end (); i ++)
cout << * i << ’ ’;
3
Algoritmi e strutture dati
La Standard Template Library del C++
Riassunto contenitori e iteratori
Mobilità degli iteratori:
• Forward iterators: possono muoversi in avanti (++)
• Bidirectional iterators: possono muoversi avanti e indietro (++, --)
– list<>,
– set<>,
– map<>
• Random access iterators: possono fare salti e calcolare distanze (++, --, +=, -=, a-b)
– vector<>,
– deque<>,
4
Algoritmi e strutture dati
La Standard Template Library del C++
Vincoli sulla genericità
Un set<T> è un albero binario di ricerca di elementi di tipo T.
Posso definire un set<T> per qualsiasi tipo T?
No. Il tipo T deve essere ordinabile. Deve essere definito l’operatore < tra due operandi
di tipo T (vincolo sulla genericità di T).
Per esempio, non può essere definito un set<> di numeri complessi.
5
Algoritmi e strutture dati
La Standard Template Library del C++
Heap in C++
6
Algoritmi e strutture dati
La Standard Template Library del C++
priority queue<T>
priority queue<T> realizza uno heap di oggetti di tipo T. Vincolo: T deve essere
ordinabile (∃ operatore <).
#include<queue>
Usa la rappresentazione linearizzata e si appoggia ad un vector<T> per la
memorizzazione.
7
Algoritmi e strutture dati
La Standard Template Library del C++
priority queue<T>
• priority_queue::priority_queue() costruttore di default ⇒ O(1)
• priority_queue::priority_queue(Iter first, Iter last) costruttore
copia dalla sequenza [first, last) e costruisce lo heap ⇒ O(n)
• int priority_queue::size() const ⇒ O(1)
• bool priority_queue::empty() const ⇒ O(1)
• const T& priority_queue::top() const ⇒ O(1)
• void priority_queue::push(const T&) ⇒ O(log n)
• void priority_queue::pop() elimina l’elemento di cima ⇒ O(log n)
• Non ci sono iteratori.
che
8
Algoritmi e strutture dati
La Standard Template Library del C++
priority queue<T>:
esempio
int main (){
priority_queue < string > q ;
q . push ( " pippo " );
q . push ( " topolino " );
q . push ( " pluto " );
q . push ( " zapotec " );
q . push ( " minnie " );
while (! q . empty ()) {
cout << q . top () << " " ;
q . pop ();
}
cout << endl ;
}
output:
zapotec topolino pluto pippo minnie
9
Algoritmi e strutture dati
La Standard Template Library del C++
Algoritmi in C++
10
Algoritmi e strutture dati
La Standard Template Library del C++
Algoritmi
La Standard Template Library fornisce un insieme di algoritmi più comuni (quicksort,
mergesort, ricerca binaria, etc.)
#include<algorithm>
Ogni algoritmo può essere applicato a molte strutture dati diverse (programmazione
generica).
11
Algoritmi e strutture dati
La Standard Template Library del C++
Sorting
void sort(Iter first, Iter last);
Esegue quicksort sugli elementi della sequenza [first, last) (⇒ O(n log n)).
Vincoli sulla genericità:
• Gli elementi devono essere ordinabili (<).
• Gli iteratori devono essere random access (scelta del perno, riconoscimento caso base).
– vector<>,
– deque<>
Ordinamento di un vettore:
vector < int > v ;
/∗ . . . ∗/
sort ( v . begin () , v . end ());
12
Algoritmi e strutture dati
La Standard Template Library del C++
Sorting
Per le liste si usa una speciale funzione membro:
list < int > l ;
/∗ . . . ∗/
l . sort ();
Esegue mergesort su tutta la lista (⇒ O(n log n)).
Vincolo: Gli elementi devono essere ordinabili (<).
13
Algoritmi e strutture dati
La Standard Template Library del C++
Ricerca lineare
Iter find(Iter first, Iter last, const T& val);
Esegue una ricerca lineare sulla sequenza [first, last). Restituisce un iteratore al primo
elemento trovato uguale a val, o last se l’elemento non esiste. (⇒ O(n)).
Vincolo: Gli elementi devono essere confrontabili (∃ operatore ==).
vector < int > v ;
/∗ . . . ∗/
if ( find ( v . begin () , v . end () , 10) != v . end ())
cout << " Ho trovato un 10! " ;
else
cout << " Non ho trovato nessun 10. " ;
14
Algoritmi e strutture dati
La Standard Template Library del C++
Ricerca binaria
bool binary search(Iter first, Iter last, const T& val);
Esegue una ricerca binaria sulla sequenza ordinata [first, last). Restituisce true se
l’elemento val è stato trovato, false altrimenti (⇒ O(log n)).
Vincoli sulla genericità:
• Elementi ordinabili (<).
• Iteratori random access.
vector < int > v ;
/∗ . . . ∗/
sort ( v . begin () , v . end ());
if ( binary_search ( v . begin () , v . end () , 10))
cout << " Ho trovato un 10! " ;
else
cout << " Non ho trovato nessun 10. " ;
15
Algoritmi e strutture dati
La Standard Template Library del C++
Ricerca binaria
Se voglio ottenere un iteratore che punta all’elemento trovato:
Iter lower bound(Iter first, Iter last, const T& val);
Esegue una ricerca binaria sulla sequenza ordinata [first, last) (⇒ O(log n)).
1. Se val esiste ed è unico: restituisce un iteratore a val.
2. Se esiste più di un val: restituisce un iteratore al primo val.
3. Se val non esiste: restituisce un iteratore all’elemento immediatamente maggiore (o
last se non esiste).
16
Algoritmi e strutture dati
La Standard Template Library del C++
Ricerca binaria
Ignora tutti gli elementi < val e prende l’estremo inferiore dei rimanenti.
val = 10
1. Se 10 esiste ed è unico:
2. Se esiste più di un 10:
3. Se val non esiste:
17
Algoritmi e strutture dati
La Standard Template Library del C++
Ricerca binaria
Esempio: raddoppio tutti gli elementi che valgono 7:
vector < int > v ;
/∗ . . . ∗/
sort ( v . begin () , v . end ());
vector < int >:: iterator i ;
i = lower_bound ( v . begin () , v . end () , 7);
// i 7 p o t r e b b e r o e s s e r e a l l a f i n e ,
// q u i n d i c o n t r o l l o a n c h e c h e i non v a d a f u o r i
while ( i != v . end () && * i == 7) {
* i *= 2;
i ++;
}
dal vettore :
18
Algoritmi e strutture dati
La Standard Template Library del C++
Algoritmi vari
• const T& max(const T& a, const T& b)
const T& min(const T& a, const T& b) Restituiscono rispettivamente l’elemento
maggiore e minore. Vincolo: definito l’operatore <.
• void swap(T& a, T& b) Scambia a con b. Ha complessità costante per i containers
(string, vector<>, list<>).
• Iter max element(Iter first, Iter last)
Iter min element(Iter first, Iter last) Restituiscono rispettivamente l’iteratore all’elemento massimo e all’elemento minimo dell’intervallo [first, last). Vincolo:
definito l’operatore <.
• Iter copy(Iter first, Iter last, Iter to) Copia gli elementi dall’intervallo
sorgente [first, last) all’intervallo destinazione che inizia da to. Restituisce un
iteratore alla fine dell’intervallo destinazione.
19
Algoritmi e strutture dati
La Standard Template Library del C++
Algoritmi vari
vector < int > a ;
vector < int > b ;
/∗ . . . ∗/
copy ( a . begin () , a . end () , b . begin ());
20
Algoritmi e strutture dati
La Standard Template Library del C++
Funtori
21
Algoritmi e strutture dati
La Standard Template Library del C++
Funtori
L’invocazione di funzione è un operatore come tutti gli altri (operatore ()).
nome f unzione(lista parametri)
Posso implementare l’operatore () in una classe:
class A {
/∗ . . . ∗/
public :
int operator () ( int arg1 , int arg2 ){ / ∗ . . . ∗ / }
};
La classe A è un funtore (oggetto che rappresenta una funzione) ed è invocabile:
int i ;
A a;
i = a (2 , 3);
22
Algoritmi e strutture dati
La Standard Template Library del C++
Funtori
void for each(Iter first, Iter last, Funct f)
Per ogni elemento nell’intervallo [first, last) esegue f(elemento).
Vincolo: f deve essere invocabile con un argomento di tipo T.
void stampa ( int a ){
if ( a >= 0 && a <= 5)
cout << a << endl ;
}
int main (){
vector < int > v ;
/∗ . . . ∗/
for_each ( v . begin () , v . end () , stampa );
}
Se voglio stampare gli interi tra 6 e 10 devo dichiarare una nuova funzione.
23
Algoritmi e strutture dati
La Standard Template Library del C++
Funtori
Definisco un funtore:
class StampaTra {
int a , b ;
public :
StampaTra ( int _a , int _b ){ a = _a ; b = _b ;}
void operator () ( int num ){
if ( num >= a && num <= b ) cout << num << endl ;
}
};
int main (){
StampaTra f (0 , 5);
StampaTra f2 (6 , 10);
vector < int > v ;
/∗ . . . ∗/
for_each ( v . begin () , v . end () , f );
for_each ( v . begin () , v . end () , f2 );
}
24
Algoritmi e strutture dati
La Standard Template Library del C++
Funtori
• void sort(Iter first, Iter last, Funct less) Ordina [first, last) usando
less come funzione di confronto. Vincolo: less deve essere invocabile con il seguente
formato: bool less(const T& a, const T& b)
• Iter find if(Iter first, Iter last, Funct test) Restituisce un iteratore al
primo elemento di [first, last) su cui test ritorna true. Vincolo: test deve essere
invocabile con il seguente formato: bool test(const T& a)
25
Algoritmi e strutture dati
La Standard Template Library del C++
Funtori
Esempio: Ordinare un vettore dal primo elemento che vale tra 1 e 5 in poi.
vector < int > v (10);
for ( int i = 0; i < 10; i ++) cin >> v [ i ];
Tra f (1 , 5); // f u n t o r e che , i n v o c a t o , r e s t i t u i s c e
// t r u e s e i l numero s t a t r a 1 e 5
vector < int >:: iterator j = find_if ( v . begin () , v . end () , f );
sort (j , v . end ());
26
Algoritmi e strutture dati
La Standard Template Library del C++
Funtori
I funtori possono essere usati anche per modificare la struttura di alcuni containers.
Esempio: set<string> con ordinamento case insensitive (“Pippo” = “pippo”).
set<string, NoCaseLess> s;
map<string, int, NoCaseLess> m;
Vincolo:
string).
NoCaseLess invocabile con il formato:
bool NoCaseLess(string,
27
Algoritmi e strutture dati
La Standard Template Library del C++
Esercizio
Scrivere un programma che fa le seguenti operazioni:
1. Prende da tastiera 10 interi e li memorizza su un vector<int> (usare un for o il
for each).
2. Prende da tastiera un numero N > 0.
3. Ordina il vector con ordinamento modulo N : a <|·|N b ⇔ |a|N < |b|N (usare il
sort a 3 argomenti).
4. Stampare su schermo il vettore ottenuto (usare un for o il for each).
N =10
28
Algoritmi e strutture dati
La Standard Template Library del C++
Esercizio - Soluzione
/∗ u t i l i p e r i l f o r e a c h ∗/
void prendi ( int & i ){ cin >> i ;}
void stampa ( int i ){ cout << i << ’ ’ ;}
/ ∗ F u n t o r e che , s e i n v o c a t o ,
t e s t a s e a è m i n o r e −modulo −N d i b ∗ /
class LessModN {
int N ;
public :
LessModN ( int _N ){ N = _N ;}
bool operator ()( int a , int b ){ return ( a % N < b % N );}
};
29
Algoritmi e strutture dati
La Standard Template Library del C++
int main (){
vector < int > v ;
int N ;
v . resize (10); // v e t t o r e d i 10 e l e m e n t i a 0
cout << " Vettore : " ;
for_each ( v . begin () , v . end () , prendi );
cout << " Modulo di ordinamento : " ;
cin >> N ;
if ( N <= 0) {
cerr << " Errore : N deve essere > 0 " << endl ;
exit ( -1);
}
sort ( v . begin () , v . end () , LessModN ( N ));
cout << " Vettore risultante : " ;
for_each ( v . begin () , v . end () , stampa );
}
30
Algoritmi e strutture dati
La Standard Template Library del C++
Esercizio 2
Scrivere un programma che fa le seguenti operazioni:
1. Prende da tastiera 10 interi e li memorizza su un vector<int> (usare un for o il
for each).
2. Ordina i primi 5 elementi (usare il sort).
3. Ordina gli ultimi 5 elementi (usare il sort).
4. Stampa su schermo il vettore ottenuto (usare un for o il for each).
5. Copia gli 8 elementi centrali su una list<int> (usare il copy).
6. Stampa su schermo la lista ottenuta (usare un for o il for each).
31
Algoritmi e strutture dati
La Standard Template Library del C++
Esercizio 2 - Soluzione
int main ( int argc , char * argv []) {
vector < int > v (10);
vector < int >:: iterator i ;
for ( i = v . begin (); i != v . end (); i ++)
cin >> * i ; // p u n t o 1
sort ( v . begin () , v . begin () + 5); // p u n t o 2
sort ( v . begin () + 5 , v . end ()); // p u n t o 3
for ( i = v . begin (); i != v . end (); i ++)
cout << * i << ’ ’; // p u n t o 4
cout << endl ;
list < int > l (8);
copy ( v . begin () + 1 , v . end () - 1 , l . begin ()); // p u n t o 5
list < int >:: iterator j ;
for ( j = l . begin (); j != l . end (); j ++)
cout << * j << ’ ’; // p u n t o 6
cout << endl ;
}
32
Algoritmi e strutture dati
La Standard Template Library del C++
Esercizio 2 - Soluzione con for each
void prendi ( int & num ){ cin >> num ;}
void stampa ( int num ){ cout << num << ’ ’ ;}
int main ( int argc , char * argv []) {
vector < int > v (10);
for_each ( v . begin () , v . end () , prendi ); // p u n t o 1
sort ( v . begin () , v . begin () + 5); // p u n t o 2
sort ( v . begin () + 5 , v . end ()); // p u n t o 3
for_each ( v . begin () , v . end () , stampa ); // p u n t o 4
cout << endl ;
list < int > l (8);
copy ( v . begin () + 1 , v . end () - 1 , l . begin ()); // p u n t o 5
for_each ( l . begin () , l . end () , stampa ); // p u n t o 6
cout << endl ;
}
33
Scarica