Les transparents du cours 3

Transcription

Les transparents du cours 3
Algorithmique, C++
Recollement d'images
Introduction à C++
Troisième partie
STL
Plan de la séance

Introduction à la STL

Les conteneurs

Les itérateurs

Quelques algorithmes
La STL en bref

Standard Template Library :
Bibliothèque de Modèles Standards



Structures de données évoluées :
listes, vecteurs, … (conteneurs)
Outils pour parcourir les conteneurs :
itérateurs
Algorithmes optimisés : fonctions de
tri, …
Objectif

Standardiser les composants usuels


Pas besoin de redéfinir une liste, un
algorithme de tri, ...
Intégrée au compilateur : pour utiliser
un composant, ajouter simplement
#include <list>

(ou #include <vector> ou autre)
Généricité :

list de int, list de vec de int, etc.
Les conteneurs

Définition : objet qui contient d'autres objets

Implémentation : modèles (templates)
paramétrés par le type des objets mémorisés

3 conteneurs de base : les séquences

vector<T>
// Vecteur : accès à un élt O(1), insertion
// ou suppression O(n) (sauf en fin)

list<T>
// Liste doublement chaînée : insertion ou
// suppr. O(1), accès à un élt aléatoire O(n)

deque<T>
// Double ended queue : intermédiaire entre
// les 2, ~ vec avec ajout en tête/queue rapide
Autres conteneurs

3 adaptateurs de séquences :




stack< T, seq<T> > // Pile (LIFO)
queue< T, seq<T> > // File (FIFO)
priority_queue< T, seq<T>, cmp<T> >
// Tas
4 conteneurs associatifs :




map<key, T, cmp> // Dictionnaire
multimap<key, T, cmp> // Dictionnaire multiple
set<key, cmp> // “Ensemble”
multiset<key, cmp> // “Ensemble” multiple
Les séquences

Méthodes disponibles pour toute séquence :

Constructeur de recopie, opérateurs == et !=

Test si vide : empty(), nb d'éléments : size()

Premier/dernier élément : front(), back()

Itérateur (sur le premier élément) : begin()

Itérateur (sur le dernier élément + 1) : end()

Insertion/suppression : push_front() (pas
vector), push_back(), pop_front() (pas
vector), pop_back(), insert(it,T)(insertion
avant it), erase(it), clear()
Vecteur

Opérateur [] (comme les tableaux)

capacity() : nombre d'élts alloués


Croissance dynamique : ajout à la fin
(push_back) => redimensionnement
(capacité * 2), coût O(n) en pire cas mais
O(1) amorti
Méthode reserve() fixe la capacité

ne change pas la taille, seule de la
mémoire est allouée)
Vecteur : exemple
#include <vector>
std::vector<int> v; // Création d'un vecteur vide
v.push_back(1); // La capacité passe à 1, v = (1)
v.push_back(2); // Capacité = 2, v = (1 2)
v.push_back(3); // Capacité = 4, v = (1 2 3)
v.reserve(5); // Capacité = 5, v = (1 2 3)
v.pop_back(); // Capacité = 5, v = (1 2)
std::cout << v[1]; // Renvoie 2
std::cout << v.capacity(); // Renvoie 5
Liste

Occupation mémoire supérieure à vector
(pointeurs en plus)

Méthode remove(val) :

supprime tous les éléments de valeur val
Méthode reverse() : inverse la liste

Méthode sort() : trie (de manière stable)

selon l'opérateur <
Méthode merge(L) : fusionne avec la liste L
en triant selon l'opérateur <


Liste : exemple
#include <list>
std::list<int> l; // Création d'une liste vide
l.push_back(1); // l = 1
l.push_front(2); // l = 2->1
l.push_back(3); // l = 2->1->3
l.reverse(); // l = 3->1->2
l.sort(); // l = 1->2->3
l.push_front(2); // l = 2->1->2->3
l.remove(2); // l = 1->3
Adaptateurs de séquences

Piles, files et tas (files de priorité)

Construits à partir d'une séquence :
Deque toujours conseillée
 Vecteur et liste pas toujours possibles
Pas d'itérateur sur la structure de données,
mais 2 méthodes : push(val) et pop()



Accès au premier/dernier élément : top()
(pile et tas), front() et back() (file)
Pile et file : exemple
#include <stack>
#include <queue>
std::stack<int, deque<int> > pile;
std::queue<int, deque<int> > file;
pile.push(1); pile.push(2); pile.push(3);
file.push(1); file.push(2); file.push(3);
std::cout << pile.top() << std::endl; // 3
std::cout << file.front() << std::endl; // 1
pile.pop(); file.pop(); // p = 2->1, f = 2->3
Conteneurs associatifs

Collections ordonnées d'éléments

Objectif : recherche rapide d'éléments à
partir d'une clé

Le type de la clé doit posséder un opérateur
de comparaison impliquant une relation
d'ordre total entre les éléments

Triple généricité :

type des éléments et type des clés

fonction de comparaison des clés
Les 4 conteneurs
associatifs

map<key, T, cmp> : dictionnaire, un seul
élément par clé



multimap<key, T, cmp> : comme map mais
plusieurs éléments par clé
set<key, cmp> : “ensemble” : valeurs et clés
confondues, on ne conserve que les clés
=> arbre équilibré de clés
multiset<key, cmp> : comme set mais peut
contenir plusieurs fois la même clé
Conteneurs associatifs :
méthodes

insert(…), erase(…) : insertion/suppression
d'un ou plusieurs éléments

find(K) : renvoie un itérateur sur le
(premier) élément dont la clé vaut K

Toutes ces méthodes sont de complexité au
pire logarithmique

count(K) : nombre d'éléments de clé K

empty(), size(), …
Conteneurs associatifs :
exemple

Opérateur de comparaison des clés :
struct compar {
bool operator() (const char* s1,const char* s2)
{ return strcmp(s1,s2) < 0; } };

Utilisation :
std::map<const char*, int, compar> nb_jours;
nb_jours[“janvier”]=31; nb_jours[“fevrier”]=28; …
std::cout << "Février : " << nb_jours[“fevrier”];
Itérateurs

Objectif : permettre de parcourir les
conteneurs de façon uniforme et générique

Principe : généralisation de la notion de
pointeur

L'expression *i a un sens ((*i).m aussi)

Opérateurs disponibles : ==, !=, =, *

Les conteneurs créent des itérateurs à
l'aide des méthodes begin(), end(), etc.

Existent en version const et non const
Les différents types
d'itérateurs



It. séquentiels unidirectionnels
(forward_iterator)
 Disposent seulement de l'opérateur ++
 Toutes structures de données de la STL
It. séquentiels bidirectionnels
(bidirectional_iterator)
 Disposent des opérateurs ++ et - Séquences et conteneurs associatifs
It. à accès direct (random_access_iterator)
 Disposent des opérateurs ++, -- et []
 vector et deque
Itérateurs : exemple
#include <vector>
std::vector<int> v;
v.resize(10); // et non reserve !
for (int i=0;i<10;i++) std::cin >> v[i];
for (vector<int>::const_iterator it=v.begin();
it!=v.end(); it++) std::cout << *it << ' ';
// Attention v.end() = après dernier élément de v
for (vector<int>::iterator it=v.begin(); it!
=v.end(); it++)
if (*it == 0) { v.erase(it); it--; }
// Efface tous les 0 du vecteur. Attention, erase()
// déplace le pointeur vers l'élément suivant
Algorithmes




Composants réalisant des traitements sur ou à partir de
conteneurs
Exemple 1 : renvoie un itérateur sur le premier élément
égal à value
template<class Iterator, class T>
Iterator find(Iterator first, Iterator last,
const T& value);
Exemple 2 : tri des élts compris entre first et last
template<class RAIterator> // RA = Random
Access
void sort(RAIterator first, RAIterator last);
Autres algorithmes : search, for_each, copy, rotate,
min, max, …
Un dernier exemple
#include <vector> #include <fstream> #include <numeric>
std::vector<int> v; ifstream f("notes.txt");
copy(istream_iterator<int>(f),
istream_iterator<int>(), back_inserter(v));
sort(v.begin(),v.end());
std::cout << “min/max : ” << v.front() << '-'
<< v.back() << std::endl;
std::cout << “médiane : ” << *(v.begin()
+v.size()/2) << std::endl;
std::cout << “moyenne : ” <<
accumulate(v.begin(),v.end(),0.0)/v.size() <<
std::endl;

Documents pareils

STL

STL std::cout << myList.front() << std::endl; std::cout << myList.back() << std::endl;

Plus en détail

Le Traitement des données avec la STL (pdf - David Saint

Le Traitement des données avec la STL (pdf - David Saint remplacement, la recherche avec un critère, le tri. Elles peuvent : • S’appliquent à tous les objets d’un conteneur ou seulement une partie. • Opérer sur 2 conteneurs de nature différents à conditi...

Plus en détail

La STL - imagecomputing.net

La STL - imagecomputing.net Toujours préférer le const_iterator si possible

Plus en détail

fichier pdf

fichier pdf v.push_back(string("Denmark")); // et oui un vector s'agrandit sans problème // (mais ça coûte cher) // aussi on fait plutôt v.resize( taillenettementplusgrande ); vector::iterator it; for ...

Plus en détail