Télécharger la présentation
Publié parAnette Jullien Modifié depuis plus de 11 années
1
Cours n° 8 Conception et Programmation à Objets
Equipe pédagogique Marie-José Caraty, Denis Poitrenaud et Mikal Ziane Cours n° 8 Conception et Programmation à Objets Réutilisation de composants de la bibliothèque standard du C++ (STL) 1/2
2
Sommaire Introduction Conteneurs 1.1. Séquences élémentaires
Conteneurs vector, deque, list 1.2. Adaptateurs de séquence Conteneurs stack, queue, priority_queue 1.3. Conteneurs associatifs Conteneur map, set, multimap, multiset Itérateurs Algorithmes Manipulations - Ordonnancement Recherche - Ensemblistes Conclusion
3
Objectifs à la conception de STL
INTRODUCTION Standard Template Library (STL) STL fournit les fonctionnalités de l'algorithmique de base Ensemble de composants techniques Types abstraits de données (TAD) correspondant aux structures de données classiques (implémentation abstraite des structures de données et de leurs méthodes associées) et d’algorithmes applicables aux TAD Objectifs à la conception de STL Structures de données et algorithmes doivent fonctionner pour tout type d'élément type prédéfini/natif du langage type utilisateur (défini par le programmeur) Efficacité vitesse d'exécution Abstraction de l'implémentation Mécanisme de généricité Fondé sur les patrons (templates) de classes, de méthodes et de fonctions Normalisée en 1995 (ANSI Draft) Source et documentation disponible sur
4
itérateur algorithme conteneur Conteneurs (container)
INTRODUCTION Composants phares de STL Conteneurs (container) Implémentation des structures de données les plus courantes avec leur allocation/désallocation mémoire automatique Itérateurs (iterator) Principes d'accès/balayage des éléments des conteneurs Algorithmes (algorithm) Implémentation d'algorithmes génériques associés itérateur algorithme conteneur
5
Conteneurs de séquence
Introduction Implémentation générique de structures de données classiques en programmation Organisation d’un ensemble fini d'éléments de même type Conteneurs de séquence Eléments organisés suivant un arrangement linéaire Séquences élémentaires (vector, deque, list) Adaptateurs de séquence (stack, queue, priority_queue) Conteneurs associatifs Eléments décrits par des paires (clé, valeur) de type quelconque et triés par ordre de clé Recherche rapide (recherche binaire) d'élément (set, map, multiset, multimap)
6
Conteneurs Adaptateurs de séquence list deque stack queue
priority_queue map multimap set multiset Conteneurs de séquence Conteneurs associatifs 1. CONTENEURS Classification Séquences élémentaires vector
7
Inclusion des headers standards de la librairie STL
1. CONTENEURS Visibilité des composants Inclusion des headers standards de la librairie STL #include <vector> // Définition de la classe vector #include <list> // Définition de la classe list #include <deque> // Définition de la classe deque #include <stack> // Définition de la classe stack #include <queue> // Définition des classes queue et priority_queue #include <map> // Définition de la classes map #include <multimap> // Définition de la classe multimap #include <set> // Définition de la classe set #include <multiset> // Définition de la classe multiset #include <algorithm> // Algorithmes génériques. Par exemple, copy(..) #include <iterator> // Définition de la classe iterator using namespace std; // Visibilité des entités déclarées dans la librairie // standard // Sans cette clause d'utilisation : utiliser // le nom qualifié // Préfixe suivi de l'opérateur de résolution de portée // Exemple : std::vector<int> V;
8
Blocs contigus d'objets (vector) ou non contigus (deque, list)
1.1. SEQUENCES ELEMENTAIRES Principes de fonctionnement Blocs contigus d'objets (vector) ou non contigus (deque, list) Insertion possible en tout point de la séquence Performance fonction du type de séquence et du point d'insertion Accès direct Insertion/suppression optimisée en fin vector deque Accès direct Insertion/suppression optimisée en début ou en fin (Double End QUEue) Accès séquentiel Insertion/suppression optimisée en tout point list
9
Méthodes communes des séquences élémentaires (1/2)
1.1 SEQUENCES ELEMENTAIRES Méthodes communes des séquences élémentaires (1/2) bool empty(); true si le conteneur est vide size_type size() const; Nombre d'éléments du conteneur size_type max_size() const; Contenance maximale du conteneur void resize(size_type, T c =T()); Redimensionnement du conteneur T& front(); Référence sur le premier élément T& back(); Référence sur le dernier élément
10
Méthodes communes des séquences élémentaires (2/2)
1.1. SEQUENCES ELEMENTAIRES Méthodes communes des séquences élémentaires (2/2) void push_back(const T& ); Ajout (recopie) de l'élément en fin void pop_back(); Suppression de l’élément en fin de séquence iterator insert(iterator, const T& = T()); Insertion d’un élément à l'emplacement spécifié par l'itérateur void insert(iterator position, iterator debut, iterator, fin) Insertion à la position spécifiée les éléments de [debut fin[ void swap(sequence <T>&back()) Echange des éléments de this avec ceux du conteneur argument void erase(iterator i); Suppression de l'élément pointé par l'itérateur i void erase(iterator debut, iterator fin); Supprime des éléments de [debut fin[
11
Définition de la classe générique vector
1.1. SEQUENCES ELEMENTAIRES Classe générique et instanciation Définition de la classe générique vector template <class T, class Alloc=alloc> class vector {...}; 2 paramètres formels génériques T : type des éléments du vecteur Alloc : type de la gestion mémoire (allocation/désallocation) Remarque : Alloc a une valeur par défaut : alloc Déclaration d’un vecteur : instanciation du générique Pour déclarer un objet de type vector, on instancie la classe générique vector en précisant (dans l’ordre et séparés par une virgule) les paramètres effectifs correspondants aux paramètres formels génériques Exemple : pour déclarer un vecteur de flottants vector <double> vi; //sans autre paramètre, //alloc (paramètre par défaut) est considéré Notation SGI vector <T, Alloc=alloc> que nous noterons vector <T>
12
vector <T> v; Déclaration d’un vecteur v d’éléments de type T
1.1. SEQUENCES ELEMENTAIRES - Conteneur VECTOR Instanciation, propriétés et méthodes spécifiques vector <T> v; Déclaration d’un vecteur v d’éléments de type T vector <T> v(n); Déclaration d’un vecteur v de n éléments de type T Extension de la structure classique de tableau (liste) Création et variation de la taille au cours de l’exécution Fonctions d’insertion et de suppression non optimisées (sauf en fin de vecteur) Méthodes spécifiques size-type capacity() const; Capacité actuelle du conteneur void reserve(size_type); Ajout de capacité T& operator [](size_type) ou T& at(size_type); Accès direct
13
Résultat d’exécution Taille : 8 – Vecteur : 10 15 23 67 43 98 34 77
1.1. SEQUENCES ELEMENTAIRES - Conteneur VECTOR Exemple #include <iostream> #include <vector> using namespace std; int main() { int tabEnt[] = {10, 15, 23, 67, 43, 98, 34, 77}; vector <int> vi; for (int i = 0; i < sizeof(tabEnt) / sizeof(int); i++) vi.push_back(tabEnt[i]); cout << "Taille : " << vi.size() << " – Vecteur : "; for (int i = 0; i < vi.size(); i++) cout << vi[i] << " "; } Résultat d’exécution Taille : 8 – Vecteur :
14
deque <T> d; Déclaration d’une deque d d’éléments de type T
1.1. SEQUENCES ELEMENTAIRES - Conteneur DEQUE Instanciation, propriétés et méthodes spécifiques deque <T> d; Déclaration d’une deque d d’éléments de type T deque <T> d(n); Déclaration d’une deque d de n d’éléments de type T Fonctionnalités voisines de celles du conteneur vector + Insertion et suppression en début de séquence plus rapide - Accès direct plus lent Méthodes spécifiques void push_front(const T&) const; Insertion d’un élément en début de séquence void pop_front(); Suppression en début de séquence T& operator [](size_type); et T& at(size_type); Accès direct
15
Résultat d’exécution Taille : 8 – Deque : 77 34 98 43 67 23 15 10
1.1. SEQUENCES ELEMENTAIRES - Conteneur DEQUE Exemple #include <iostream> #include <deque> using namespace std; int main() { int tabEnt[] = {10, 15, 23, 67, 43, 98, 34, 77}; deque <int> di; for (int i = 0; i < sizeof(tabEnt) / sizeof(int); i++) di.push_front(tabEnt[i]); cout << "Taille : " << di.size() << " – Deque : "; for (int i = 0; i < di.size(); i++) cout << di[i] << " "; } Résultat d’exécution Taille : 8 – Deque :
16
list <T> l; Déclaration d’une liste l d’éléments de type T
1.1. SEQUENCES ELEMENTAIRES - Conteneur LIST Instanciation, propriétés et méthodes spécifiques (1/2) list <T> l; Déclaration d’une liste l d’éléments de type T list <T> l(n); Déclaration d’une liste l de n d’éléments de type T Spécialisation de la structure classique de liste + Fonctions rapides d’insertion et de suppression - Accès séquentiel fonctions rapides (tri, concaténation, …) Méthodes spécifiques void push_front(const T&) const; Insertion d’un élément en début de séquence void pop_front(); Suppression de l’élément en début de séquence void remove(const& T valeur); Suppression de tous les éléments égaux à valeur void remove_if(Predicate pred); Suppression de tous les éléments vérifiant pred
17
Méthodes spécifiques (2/2)
1.1. SEQUENCES ELEMENTAIRES - Conteneur LIST Méthodes spécifiques (2/2) void sort([Compare cmp]); Tri des éléments selon l'opérateur < ou le foncteur cmp void reverse([Compare cmp])); Inversion de l'ordre des éléments selon l'opérateur < ou le foncteur cmp void unique([Compare cmp]); Suppression sur une liste triée des éléments en double void merge(list<T> & x [, Compare cmp]); Fusion de la liste triée avec une autre liste x triée de même type, x est vidé. void splice(iterator i, list<T>& x); Déplacement de la liste x dans la liste this avant l’élément pointé par l’itérateur i void splice(iterator i, list<T>& x, iterator j); Déplacement de l’élément de x pointé par l’itérateur j dans la liste this avant l’élément pointé par l’itérateur i void splice(iterator i, list<T>& x, iterator debut, iterator fin); Déplacement de la séquence d’éléments [debut fin[ de x dans la liste this avant l’élément pointé par l’itérateur i
18
Variable qui repère la position d'un élément dans un conteneur
1.1. SEQUENCES ELEMENTAIRES - Conteneur LIST Rôle des itérateurs Variable qui repère la position d'un élément dans un conteneur L’itérateur permet d’accéder/balayer les éléments d'un conteneur A chaque conteneur son type d’itérateur Quelque soit la classe conteneur : 2 méthodes membres Début de la collection (position du premier élément) Itérateur renvoyé par la méthode membre begin() Fin de la collection (position de l'élément "juste après le dernier") Itérateur renvoyé par la méthode membre end() Accès à l’élémént repéré par l’itérateur It : *It Exemple : vector <int> V; V.begin() V.end() 12 3 25 7 39 27
19
Résultat d’exécution Exemple #include <iostream>
1.1. SEQUENCES ELEMENTAIRES - Conteneur LIST Exemple #include <iostream> #include <list> using namespace std; int main() { int tabEnt[] = {10, 15, 23, 67, 43, 98, 34, 77, 10}; list <int> li; for (int i = 0; i < sizeof(tabEnt) / sizeof(int); i++) li.insert(li.begin(), tabEnt[i]); li.sort(); li.unique(); cout << "Liste : "; for (list <int>::iterator i = li.begin(); i != li.end(); i++) cout << *i << " "; } Résultat d’exécution Liste :
20
Conteneurs implémentés à partir de séquences élémentaires stack
1.2. ADAPTATEURS DE SEQUENCE Introduction Conteneurs implémentés à partir de séquences élémentaires stack Structure de données de pile - Last In First Out (LIFO) Insertions et retraits sur le haut de la pile queue Structure de données de file - First In First Out (FIFO) Insertions en fin et retraits en début priority_queue Structure de données de file avec priorité (fonction d'un prédicat) Après insertion d’élément, file maintenue triée par ordre croissant de priorité Insertions en fin et accès/retraits de l'élément de plus forte priorité Pas d’autres accès (direct ou séquentiel) Par conséquent, pas d’accès/balayage par itérateur
21
Implémentation d’une structure abstraite de pile Méthodes spécifiques
1.2. ADAPTATEURS DE SEQUENCE – Adaptateur STACK Instanciation, propriétés et méthodes spécifiques stack<T, Sequence=deque<T> > p; Déclaration d’une pile p d’éléments de type T Sequence : séquence élémentaire (générique) Implémentation d’une structure abstraite de pile Méthodes spécifiques bool empty(); true si la pile est vide, false sinon size_type size() const; Taille de la pile T& top() : Lecture du sommet de la pile (sans dépiler l’élément) void push(const T& ); Empiler l'élément void pop(); Dépiler un élément
22
Résultat d’exécution Exemple #include <iostream>
1.2. ADAPTATEURS DE SEQUENCE – Adaptateur STACK Exemple #include <iostream> #include <vector> #include <stack> using namespace std; int main() { float tabFlt[] = {10.2, 15.3, 23.1, 67.2, 43.4, 98.8, 34.6}; stack <float, vector<float> > pf; for (int i = 0; i < sizeof(tabFlt) / sizeof(float); i++) pf.push(tabFlt[i]); while (pf.empty() == false) { cout << pf.top() << " "; pf.pop(); } Résultat d’exécution
23
Pile implémentée par un vecteur
1.2. ADAPTATEURS DE SEQUENCE – Adaptateur STACK Exemple Pile implémentée par un vecteur stack <int, vector<int> > S; S.push(8); S.push(4); // assert(S.size() ==2 ); // assert(S.top() == 4); S.pop(); // assert(S.top() == 8); S.pop(); // assert(S.empty());
24
Implémentation d’une structure abstraite de file Fonctions membres
1.2. ADAPTATEUR DES SEQUENCES – Adaptateur QUEUE Instanciation, propriétés et méthodes spécifiques queue<T, Sequence=deque<T> > f; Déclaration d’une file f d’éléments de type T Sequence : séquence élémentaire (générique) Implémentation d’une structure abstraite de file Fonctions membres bool empty(); true si la file est vide, false sinon size_type size() const; Taille de la file T& front() : Lecture de la tête de la file (sans retirer l’élément) void push(const T& ); Ajout de l'élément en queue (sans retirer l’élément) void pop(); Suppression d’un élément en tête de file
25
Résultat d’exécution p a r i s Exemple #include <iostream>
1.2. ADAPTATEUR DES SEQUENCES – Adaptateur QUEUE Exemple #include <iostream> #include <list> #include <queue> using namespace std; int main() { char tabChr[] = {'p', 'a', 'r', 'i', 's'}; queue <char, list<char> > fa; for (int i = 0; i < sizeof(tabChr) / sizeof(char); i++) fa.push(tabChr[i]); while (fa.empty() == false) { cout << fa.front() << " "; fa.pop(); } } Résultat d’exécution p a r i s
26
File implémentée par une deque
1.2. ADAPTATEUR DES SEQUENCES – Adaptateur QUEUE Exemple File implémentée par une deque queue <int> Q; Q.push(8); Q.push(2); // assert(Q.size() == 2); // assert(Q.back() == 2); // assert(Q.front() == 8); Q.pop(); // assert(Q.front() == 2); Q.pop(); // assert(Q.empty());
27
Implémentation d’une structure abstraite de file à priorité
1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Instanciation, propriétés et méthodes spécifiques priority_queue<T, Sequence=deque<T>, Compare=less<T> > fp; Déclaration d’une file à priorité fp d’éléments de type T Sequence : séquence élémentaire (générique) Compare : prédicat binaire générique (foncteur) de comparaison d’éléments Implémentation d’une structure abstraite de file à priorité Méthodes spécifiques bool empty(); true si la file est vide, false sinon size_type size() const; Taille de la file T& top() : Lecture de la tête de la file (élément prioritaire) void push(const T& ); Ajout de l'élément en queue void pop(); Suppression d’un élément en tête
28
6 foncteurs prédéfinis (pour les types natifs) en C++
1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Opérateur de comparaison Compare : définition du critère de priorité à partir d’un prédicat binaire de comparaison bool Compare<T> (const T& arg1, const T& arg2); paramètre générique : T, le type des éléments retourne vrai si arg1 et arg2 sont ordonnés, faux sinon 6 foncteurs prédéfinis (pour les types natifs) en C++ redéfinissant les opérateurs relationnels : equal_to <T> retourne (arg1 == arg2) not_equal_to <T> retourne (arg1 != arg2) greater <T> retourne (arg1 > arg2) less <T> retourne (arg1 < arg2) greater_equal <T> retourne (arg1 >= arg2) less_equal <T> retourne (arg1 <= arg2) Pour un type utilisateur T : Nécessité de redéfinir l’opérateur relationnel correspondant au foncteur choisi
29
Résultat d’exécution s r p i a Exemple #include <iostream>
1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Exemple #include <iostream> #include <deque> #include <queue> using namespace std; int main() { char tabChr[] = {'p', 'a', 'r', 'i', 's'}; priority_queue<char, deque<char>, less<char> > fp; for (int i = 0; i < sizeof(tabChr) / sizeof(char); i++) fp.push(tabChr[i]); while (fp.empty() == false) { cout << fp.top() << " "; fp.pop(); } Résultat d’exécution s r p i a
30
Foncteur less<int> - élément prioritaire, de plus forte priorité
1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Exemple – T est un type prédéfini Foncteur less<int> - élément prioritaire, de plus forte priorité priority_queue <int> P; //ordre décroissant de priorité P.push(1); P.push(8); P.push(4); // assert(P.size()==3); // assert(P.top() == 8); P.pop(); // assert(P.top() == 4); P.pop(); // assert(P.top() == 1); P.pop(); // assert(P.empty()); Foncteur greater<int> - élément prioritaire, de plus faible priorité priority_queue <int, greater<int> > P; //ordre croissant //de priorité P.push(1); P.push(8); P.push(4); // assert(P.size()==3); // assert(P.top() == 1); P.pop(); // assert(P.top() == 8); Priorité décroissante Valeurs Priorité décroissante Valeurs
31
float pV_; // prix de vente float pR_; // prix de revient
1.2. ADAPTATEUR DES SEQUENCES – Adaptateur PRIORITY_QUEUE Exemple – T est un type utilisateur Exemple : Gestion de produits par priorité de marge bénéficiaire Le produit prioritaire dans la file est celui de plus forte marge class Produit { float pV_; // prix de vente float pR_; // prix de revient // Définitions du constructeur, des accesseurs,… }; priority_queue <Produit> P;// Gestion des produits par une // une file à priorité implémentée // par une deque et less L’opérateur "<" doit être redéfini pour le type Produit bool operator<(const Produit& P1, const Produit& P2) { return (P1.getPV()-P1.getPR())<(P2.getPV()-P2.getPR()) }
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.