Conteneurs STL.

Slides:



Advertisements
Présentations similaires
Erratum C Surcharge For(int x=0; … 2.
Advertisements

Cours n° 7 Standard Template Library II.
Cours n° 6 Standard Template Library I.
C++ 6ème cours Patrick Reuter maître de conférences
Au programme du jour …. Un peu plus de structures de données
Intégration Excel / C++
Cours n° 9 Conception et Programmation à Objets
Cours n° 8 Conception et Programmation à Objets
La programmation générique avec la STL EIUMLV - Informatique et Réseaux 99 Benoît ROMAND.
Approfondissement du langage
JAV - TD 6 Structures de données JAVA
Structures et unions types énumérés Qu'est-ce qu'une structure
Regrouper des éléments de même type et pouvoir y accéder à laide dun identificateur et dun indice. Objectif des tableaux.
Leçon 6 : Structures de données dynamiques IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier.
Bibliothèque standard du C++
8PRO100 Éléments de programmation Allocation dynamique de la mémoire.
TRAITEMENT DE STRUCTURES
Chapitre VIII Structures dobjets. Chapitre VIII - Structures d'objets2 Structures d objets Il existe plusieurs relations entre les classes. Lhéritage.
IFT-2000: Structures de Données Listes chaînées Dominic Genest, 2009.
Standard Template Library (STL)
Structures de données IFT-2000
Master 1 SIGLIS Java Lecteur Stéphane Tallard Chapitre 5 – Héritage, Interfaces et Listes génériques.
Traiter des Données avec la STL
Programmation Initiation Aux Langages C et C++ (3) Bruno Permanne 2006.
Structures de données IFT Abder Alikacem La classe vector Édition Septembre 2009 Département dinformatique et de génie logiciel.
Structures de données IFT Abder Alikacem La classe string Département dinformatique et de génie logiciel Édition Septembre 2009 Département dinformatique.
Structures de données IFT Abder Alikacem Espace de nommage Département d’informatique et de génie logiciel Édition Septembre 2009.
Structures de données IFT-2000
Structures de données IFT-2000 Abder Alikacem Espace de nommage Département dinformatique et de génie logiciel Édition Septembre 2009 Département dinformatique.
Structures de données IFT-2000 Abder Alikacem La librairie STL du C++ Département dinformatique et de génie logiciel Édition Septembre 2009.
Structures de données IFT-2000
Structures de données IFT-2000 Abder Alikacem Standard Template library Édition Septembre 2009 Département dinformatique et de génie logiciel.
Programme de baccalauréat en informatique Programmation Orientée Objets IFT Thierry EUDE Module 7 : Classes et fonctions paramétrables Département.
GPA789 Analyse et conception orientées objet 1 Professeur: Tony Wong, Ph.D., ing. Chapitre 6 Correspondance UML et C++
Un langage de programmation hybride
1 Fonction : surcharge de sélection La surcharge de sélection consiste à implanter plusieurs méthodes de même nom dans une même classe à condition que.
Standard Template Library
Programme de baccalauréat en informatique Programmation Orientée Objets IFT Thierry EUDE Module 6. Gestion des erreurs et des exceptions : Fonctionnement.
Masters IIGLI et IGLII – Programmation générique et conception objet – – Claude Montacié 1 Cours n° 4 Polymorphisme II.
Structures de données IFT-2000
Structures de données IFT-2000
La librairie assert.h.
Faculté Polytechnique de Mons
Le langage C Structures de données
9ième Classe (Mardi, 4 novembre) CSI2572. H Nous avons vu comment utiliser les directives #define #ifndef #endif Pour s’assurer de l’inclusion unique.
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
La notion de type revisitée en POO
Héritage multiple En langage C++, il est possible d’utiliser l’héritage multiple. Il permet de créer des classes dérivées à partir de plusieurs classes.
Programmation objet La base.
Templates, Containers et STL Structures de données de base tableau, liste chaînée file, pile, arbres, hashtable collection, ensemble 2 caractéristiques.
Cours C++ Fonctions Surcharge d’opérateurs Passage d’arguments
ETNA – 1ème année Guillaume Belmas –
Les classes présenté par: RAHMOUNE RIME / ZEKRI SELMA.
Les surcharges d'opérateurs
Conception de Programmes - IUT de Paris - 1ère année – Cours 8 – Les entrées/sorties Comment fonctionnent les opérateurs > pour les types élémentaires.
Conception de Programmes - IUT de Paris - 1ère année – Cours 6 - Les opérateurs L’amitié Les opérateurs –Introduction –Surcharge par fonction.
Conception de Programmes - IUT de Paris - 1ère année Conception de Programmes Objectifs et organisation du cours Introduction à la P.O.O.
Les bases de l’algorithmique
Langage de programmation
8PRO107 Éléments de programmation Les adresses et les pointeurs.
8PRO107 Éléments de programmation Les tableaux. Étude de cas 1 Description du problème : Lire une liste d’entiers et l’afficher d’abord dans le même ordre.
Structures de données IFT-2000 Abder Alikacem La STL du C++. La récursivité Semaine 9 Département d’informatique et de génie logiciel Édition Septembre.
1 Listes des méthodes de la classe string, et exemples.
Structures de données IFT-2000 Abder Alikacem Laboratoire #1 Département d’informatique et de génie logiciel Édition Septembre 2009.
Exception Handling "Unfortunately, it's almost accepted practice to ignore error conditions, as if we're in a state of denial about errors." Bruce Eckel.
Conception de Programmes - IUT de Paris - 1ère année Les classes Introduction Déclaration d’une classe Utilisation d’une classe Définition des.
Informatique 2A Langage C 5ème séance. Déroulement de la séance 5 1 ère partie Étude des chaînes de caractères 2 ème partie Les structures 3.
M. BENJELLOUN : 2005 Le but final est de programmer un jeu où l'ordinateur choisira un nombre aléatoire entre 0 et 100 que vous devez deviner.
Transcription de la présentation:

Conteneurs STL

Bibliothèque de modèles standards (STL – Standard Template Library) STL est une bibliothèque de classes du type container (comme par exemple des listes chaînées), d'algorithmes et d'outils d'itération. Un conteneur est une structure qui permet d'organiser un ensemble d'objets du même type en séquence. Voici par exemple différents types de conteneurs: les listes (list), les vecteurs (vector), les ensembles (set), les listes d'associations (map). La notion de conteneur est importante. Il s'agit de structures algorithmiques permettant d'organiser un ensemble de données en séquence, puis de parcourir ces données.

Namespaces : La bibliothèque standard se trouve entièrement dans le namespace std. Un namespace (espace de nom ) est un moyen de lutter contre les conflits de noms, par exemple le type list s'appelle en réalité std::list. Cependant pour ne pas alourdir les exemples de code (et parce que en général, l'emploi de directives using permet ce raccourci), nous omettrons le std::.

Certains noms sont assez communs et peuvent avoir été utilisés par plusieurs librairies. Les namespace sont une solution à ce problème. Le fichier suivant namespace Lib // ouverture du namespace { class Toto // ... }; }; // fermeture du namespace définit le type Lib::Toto. Cependant quand aucune ambiguïté n'existe, le programmeur peut utiliser le type Toto directement. Pour utiliser le contenu du namespace Lib, il faut inclure using namespace Lib;

La notion d'itérateur : L'itérateur est une généralisation des pointeurs. Il permet de parcourir en séquence les éléments d'un conteneur. Pour comprendre l'analogie, regardons le code C++ classique suivant: 1 void fonction(char* t,const int& taille) 2 { 3 for(int i=0;i<taille;i++) 4 { 5 t[i] = t[i]+2; 6 } 7 }

Afin d'optimiser un tel parcours de tableau (pour éviter à la ligne 5, de calculer deux fois un déplacement de i par rapport à l'adresse de base de t), on peut remplacer ce code par le code suivant: void fonction(char* t,const int& taille) { for(char *p = t,*pstop = t+taille;p < pstop;p++) *p = (*p)+2; }

vector<int>::iterator i; Pour que cette itérateur pointe sur le premier élément d'une liste donnée, on utilise la méthode begin() de ce vecteur comme ci-dessous: vector<int> v; vector <int>::iterator i = v.begin();

Ainsi la traduction en STL de l'exemple précédent est: void fonction(vector<char>& t) { for (vector<char>::iterator i = t.begin(),istop=t.end(); i != istop;++i) *i = (*i)+2; }

Exemple : // fichier vect.cpp (exemple des vecteurs : conteneur vector) #include <iostream> #include <vector> using namespace std; class Cercle { private: double rayon; public: Cercle(double rayon = 5.0) { this->rayon = rayon; } double surface() { return 3.14159* rayon*rayon; void afficher(char * mess = "") { cout << mess << "<rayon: " << rayon << ", surface: " << surface() << ">\n"; };

//afficher void afficher(vector<Cercle> vect, char * message) { if ( vect.size() == 0 ) cout << message << " est vide\n"; else { int rang = 0; cout << "Contenu de " << message << " de taille " << vect.size() << " :\n"; for ( vector<Cercle>::iterator iv = vect.begin(); iv != vect.end(); iv++) { cout << ++ rang << ") "; iv -> afficher(); } cout << endl; }

// deuxième manière pour afficher void afficher(char * message, vector<Cercle> vect) { if ( vect.size() == 0 ) cout << message << " est vide\n"; else { int rang = 0; cout << "(Acces via []) Contenu de " << message << " de taille " << vect.size() << " :\n"; for ( int i = 0 ; i < vect.size() ; i++) { cout << ++ rang << ") "; vect[i].afficher(); } cout << endl; }} // troisième manière pour afficher void afficher(vector<Cercle> vect) { cout << "Vecteur est vide\n"; cout << "Vecteur de taille " << vect.size() << " :\n"; for(vector<Cercle>::reverse_iterator iv =vect.rbegin(); iv != vect.rend(); iv++) { cout << ++ rang << ")"; iv -> afficher();

int main(){ vector<Cercle> vect1; afficher(vect1, "vect 1 au debut"); vect1.insert(vect1.begin(), Cercle(10.2)); vect1.insert(vect1.end(), Cercle(6.8)); vect1.insert(vect1.end(), Cercle(12.4)); vect1[0].afficher("premier cercle: "); afficher(vect1, "vect 1 apres quelques ajouts"); afficher("vect 1 (par la deuxieme maniere)",vect1); cout << "\n(par la troisieme maniere)Parcourir en sens inverse:\n"; afficher(vect1); system("pause"); }

Classe list : La classe list est un conteneur ou chaque élément de la liste a son propre segment de mémoire et pointe son prédécesseur et son successeur (liste doublement chainée). Il faut inclure : #include <list> using namespace std ;

Exemple : // fichier list.cpp (exemple des listes : conteneur list) #include <iostream> #include <list> using namespace std; /* afficher le contenu d'une liste utilisant des itérateurs */ void afficher(list<int> liste, char * message) { if ( liste.size() == 0 ) cout << message << " est vide\n"; else { cout << "Contenu de " << message << ":\n"; for (list<int>::iterator il = liste.begin(); il != liste.end(); il++) cout << *il << endl; cout << endl; // première et dernière valeur de la liste cout << "Premier element : " << liste.front() << endl; cout << "Dernier element : " << liste.back() << endl; }

void demo1() { list<int> liste1; // liste VIDE au début cout << "\n\nDemo 1:\n\n"; afficher(liste1, "liste1 au debut"); // ajouter des multiples de 5 entre 1 et 50 au début de la liste for (int k = 1 ; k <= 50 ; k++) if (k % 5 == 0) liste1.insert(liste1.end(), k); afficher(liste1, "liste1 avec des multiples de 5 entre 1 et 50"); list<int>::iterator zz = liste1.end(); zz--; cout << " ****************** " << * zz << " *********** \n"; // modifier la valeur du 1er élément liste1.front() += 70; // modifier la valeur du dernier élément liste1.back() *= 2;

// supprimer tous les 25 de la liste liste1.remove(25); afficher(liste1, "liste1 modifiee"); // trier (sort) la liste liste1.sort(); afficher(liste1, "liste1 apres le tri"); // supprimer le début et la fin de la liste: liste1.pop_front(); liste1.pop_back(); afficher(liste1, "liste1 apres avoir retire le 1er et le dernier"); // ajouter au début et à la fin de la liste liste1.push_front(30); liste1.push_front(45); liste1.push_back (15); liste1.push_back (50); liste1.push_back (30); afficher(liste1, "liste1 apres avoir ajoute quelques val. au debut et a la fin"); afficher(liste1,"liste1 apres encore trie"); // enlever des valeurs répétées liste1.unique(); afficher(liste1, "liste1 apres avoir enleve des val. doubles"); }

// une manière pour créer une liste à partir d'un tableau void creer(list<int> & liste, int tableau[], int nbElem) { for (int i = 0 ; i < nbElem; i++) liste.insert(liste.end(), tableau[i]); } void demo2() { cout << "\n\nDemo 2:\n\n"; int age1[] = { 23, 15, 20, 18, 22, 40, 18, 32 }, age2[] = { 15, 41, 22, 18, 26 }; list<int> liste1, liste2; creer(liste1, age1, 8); creer(liste2, age2, 5); afficher(liste1, "liste 1 apres la creation"); afficher(liste2, "liste 2 apres la creation"); getchar(); liste1.sort(); liste2.sort(); // fusion de 2 listes liste1.merge(liste2); afficher(liste1, "liste 1 apres la fusion avec liste 2"); int main() { demo1(); demo2();

STL vector et list Les tableaux (vector) La classe vector est définie dans le fichier d'entête : #include <vector> Le tableau est le conteneur le plus pratique de la STL. Il encapsule efficacement les tableaux dynamiques en gérant la réallocation et les recopies. Un tableau connait 2 valeurs: sa taille: le nombre d'éléments qu'il contient, sa capacité: le nombre d'éléments qu'il peut contenir. Quand l'ajout d'un élément entraîne (taille>capacité) alors le tableau se réalloue en doublant sa capacité (stratégie classique). Pour déclarer un tableau contenant des int, on utilisera : vector<int> v; Le tableau a alors une taille nulle (on ne s'occupe pas de sa capacité). Pour ajouter des éléments, on peut utiliser push_back,push_front.

Méthodes Description begin() renvoie un itérateur sur le premier élément du vecteur. end() renvoie un itérateur sur le dernier élément du vecteur. assign() remplit le vecteur à la manière des constructeurs : b.assign(a.begin(),a.end()) ; ceci rempli le vecteur b avec le contenu du vecteur a. Une autre utilisation de assign() : b.assign(10,0) ; rempli les dix premiers élément avec la valeur 0. at() renvoie l’élément situé à la ième position : a.at(10) ; renvoie l’élément situé à la 11ième position (les vecteurs commencent à l’indice 0)

front() renvoie le premier élément du vecteur (ne renvoie pas un itérateur). back() renvoie le dernier élément du vecteur (ne renvoie pas un itérateur). capacity() renvoie le nombre de case mémoire disponible avant de réallouer de la mémoire clear() supprime tous les éléments du vecteur. empty() renvoie un booléen indiquant si le vecteur est vide (true) ou non (false) erase() Supprime un élément ou une plage de valeur : a.erase(10) ; //supprime le 11ème élément. a.erase(a.begin(),a.end()) ; // equivalent à a.clear() ; insert() insère un ou plusieurs éléments dans un vecteur. a.insert(10,2) ; //insère la valeur 2 à la 11 ème place. a.insert(10,2,3) ; //insère 2 fois la valeur 3 à partir de la 11ème position. pop_back() supprime et renvoie le dernier élement du vecteur.

push_back() insère un élément à la fin du vecteur. reserve() ajoute n cases mémoires au vecteur. resize() change la taille du vecteur. size() renvoie le nombre d’élément du tableau (attention différent de capacity() ) swap() échange deux éléments de deux vecteurs.

Pour accéder directement aux éléments d'un tableau, en lecture ou en écriture, on utilise la notation [] classique: #include <vector> #include <iostream> using namespace std; int main(){ vector<int> v; v.push_back(3); // le tableau vaut [3] et est de taille 1 v.push_front(4); // le tableau vaut [4,3] et est de taille 2 cout<<v[0]; // renvoie 4 v[1] = 5; cout<<v[1]; // renvoie 5 }

Attention, aucun contrôle de dépassement d'indice n'est effectué (sinon la classe serait trop lente et pas assez générique). Si vous tentez d'accéder un élément au delà de la taille du tableau, vous risquez le plantage

Les listes (list) La classe list est définie dans le fichier d'entête : #include <list> Pour déclarer une liste contenant des int, on utilisera : list<int> l;

Pour insérer ou retirer des éléments dans la liste, on utilisera les commandes suivantes: #include <list> using namespace std; void main(){ list<int> l; l.push_front(3); // la liste vaut 3::[] l.push_front(2); // la liste vaut 2::3::[] l.push_back(4); // la liste vaut 2::3::4[] l.pop_front(); // la liste vaut 3::4[] l.pop_back(); // la liste vaut 3::[]}

Les fonctions pop_back et pop_front ne retournent pas de valeurs Les fonctions pop_back et pop_front ne retournent pas de valeurs. Elles ne font que dépiler la valeur de queue ou de tête. Pour accéder à la valeur de queue ou de tête, sans les dépiler, on utilisera: l.front(); // Retourne la valeur en tête de liste l.back(); // Retourne la valeur en queue de liste Il est à noter que ces 2 fonctions retournent des références, c'est à dire qu'on peut s'en servir pour modifier le premier où le dernier élément d'une liste comme dans l'exemple ci-dessous: l.front() = 4;

void push_back(const T& x); Les méthodes: size_t size() const; Nombre d’élément.   void push_back(const T& x); Ajoute l’élément x en fin de liste. void pop_back(); Supprime le dernier élément de la liste. iterator insert(iterator position, const T& x); Insert l’élément x devant l’élément désigné par position. iterator insert(iterator position); Insert un élément construit par défaut devant l’élément désigné par position. void insert(iterator position, const_iterator first, const_iterator last); Insert une séquence d’élément désigné par first et last devant l’élément désigné par position. iterator erase(iterator position); Efface l’élément à la position donnée. iterator erase(iterator first, iterator last); Efface les éléments entre first et last exclus. void clear(); Efface tous les éléments de la list.

Les méthodes spécifique à la classe List: void remove(T valeur) Supprime tous les éléments égaux à valeur.   void sort() Tri la liste dans l’ordre croissant. void unique() Elimine les éléments en double dans une liste triée. void merge(const list<T>) Fusionne la liste list avec la liste concernée. A la fin de l’opération, list est vide.