Conteneurs de la STL
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 71 sur 104.
Les conteneurs STL sont des classes modèles qui stockent et organisent des collections d’objets. Chaque type de conteneur est optimisé pour différents schémas d’accès et opérations. Choisir le conteneur adapté à vos besoins peut avoir un impact significatif sur les performances de votre programme.
Les conteneurs séquentiels maintiennent les éléments dans un ordre précis :
#include <vector>
#include <list>
std::vector<int> vec = {1, 2, 3}; // Tableau dynamique, accès aléatoire rapide
vec.push_back(4); // Ajouter à la fin : O(1) amorti
int x = vec[2]; // Accès par index : O(1)
std::list<int> lst = {1, 2, 3}; // Liste doublement chaînée
lst.push_front(0); // Ajouter au début : O(1)
lst.push_back(4); // Ajouter à la fin : O(1)Les conteneurs associatifs stockent les éléments dans un ordre trié pour une recherche rapide :
#include <map>
#include <set>
std::set<int> s = {3, 1, 4, 1}; // Éléments uniques triés : {1, 3, 4}
s.insert(2); // Insertion : O(log n)
bool found = s.count(3); // Vérifier l'existence : O(log n)
std::map<std::string, int> ages; // Paires clé-valeur, triées par clé
ages["Alice"] = 25; // Insertion/mise à jour : O(log n)
ages["Bob"] = 30;
std::cout << ages["Alice"]; // Accès : O(log n)Les conteneurs non ordonnés utilisent des tables de hachage pour une recherche encore plus rapide en moyenne :
#include <unordered_map>
std::unordered_map<std::string, int> scores;
scores["player1"] = 100; // Insertion : O(1) en moyenne
scores["player2"] = 200;
std::cout << scores["player1"]; // Accès : O(1) en moyenneUtilisez vector lorsque vous avez besoin d’un accès aléatoire rapide, list pour des insertions fréquentes au milieu, map/set lorsque vous avez besoin de données triées, et unordered_map lorsque la vitesse de recherche est essentielle et que l’ordre n’a pas d’importance.
Défi
FacileConstruisons un système de gestion des notes des étudiants qui montre comment différents conteneurs STL répondent à différents besoins. Tu utiliseras plusieurs types de conteneurs pour organiser efficacement les données des étudiants, en choisissant le conteneur approprié pour chaque tâche.
Tu créeras deux fichiers pour organiser ton code :
GradeManager.h: définir une classeGradeManagerqui utilise plusieurs conteneurs STL pour gérer les informations des étudiants.Ta classe doit utiliser :
- Un
std::vector<std::string>pour stocker les noms des étudiants dans l'ordre où ils ont été ajoutés - Une
std::map<std::string, int>pour associer chaque nom d'étudiant à sa note - Un
std::set<int>pour suivre toutes les notes uniques qui ont été attribuées
Implémente ces méthodes :
addStudent(const std::string& name, int grade): ajoute un étudiant et sa note dans les trois conteneursgetGrade(const std::string& name): renvoie la note correspondant à un nom d'étudiant donné en utilisant la mapprintRoster(): affiche tous les noms des étudiants dans l'ordre où ils ont été ajoutés (depuis le vector), chacun sur une nouvelle ligneprintGrades(): affiche tous les étudiants avec leurs notes dans l'ordre alphabétique (la map s'en charge automatiquement), au formatname: gradesur chaque ligneprintUniqueGrades(): affiche toutes les notes uniques dans l'ordre croissant (le set s'en charge), séparées par des espaces et suivies d'un saut de ligne
- Un
main.cpp: lire les entrées et montrer comment chaque type de conteneur répond à un besoin différent.Lis six entrées (chacune sur une ligne distincte) :
- Nom du premier étudiant
- Note du premier étudiant (entier)
- Nom du deuxième étudiant
- Note du deuxième étudiant (entier)
- Nom du troisième étudiant
- Note du troisième étudiant (entier)
Crée un
GradeManageret ajoute les trois étudiants. Montre ensuite les différents comportements des conteneurs :- Afficher
Roster (insertion order):, puis appelerprintRoster() - Afficher
Grades (alphabetical):, puis appelerprintGrades() - Afficher
Unique grades:, puis appelerprintUniqueGrades() - Rechercher la note du deuxième étudiant et afficher
<name>'s grade: <grade>
Par exemple, avec les entrées Charlie, 85, Alice, 90, Bob, 85 :
Roster (insertion order):
Charlie
Alice
Bob
Grades (alphabetical):
Alice: 90
Bob: 85
Charlie: 85
Unique grades:
85 90
Alice's grade: 90Remarque que le vector préserve l'ordre d'insertion (Charlie, Alice, Bob), que la map trie automatiquement selon la clé (Alice, Bob, Charlie) et que le set ne stocke que les valeurs uniques dans l'ordre trié (85 apparaît une seule fois, et non deux). Chaque type de conteneur excelle dans des tâches différentes !
Essayez vous-même
#include <iostream>
#include <string>
#include "GradeManager.h"
using namespace std;
int main() {
// Lire les entrées pour trois étudiants
string name1, name2, name3;
int grade1, grade2, grade3;
cin >> name1;
cin >> grade1;
cin >> name2;
cin >> grade2;
cin >> name3;
cin >> grade3;
// TODO: Créer un objet GradeManager
// TODO: Ajouter les trois étudiants au GradeManager
// TODO: Print "Roster (insertion order):" and call printRoster()
// TODO: Print "Grades (alphabetical):" and call printGrades()
// TODO: Print "Unique grades:" and call printUniqueGrades()
// TODO: Rechercher la note du deuxième étudiant et afficher "<name>'s grade: <grade>"
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesGénération et compilation en C++Fichiers d’en-tête et fichiers sourceEspaces de noms et portéeIntroduction à la POO en C++Classes et objetsLe pointeur « this »Méthodes (fonctions membres)Attributs (membres de données)Bases des constructeurs et destructeursRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d’instance et statiquesAccesseurs et mutateursFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d’accès de l’héritageOrdre d’appel des constructeurs et destructeursRedéfinition des méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif : hiérarchie des employés10Vue d’ensemble de la STL
Vue d’ensemble et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - fréquence des mots13Modèles de conception, partie 1
Introduction aux modèles de conceptionModèle SingletonFabrique et fabrique abstraiteModèle BuilderModèle ObserverModèle Strategy2Gestion de la mémoire
Mémoire de pile ou de tasPointeurs et référencesMémoire dynamique (new/delete)Pointeurs intelligents en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d’accès en C++Spécificateurs d’accès en profondeurMasquage de l’informationStruct vs classeClasses imbriquées et internesRécapitulatif - Système de gestion des dossiers étudiants8Polymorphisme
Polymorphisme à la compilation vs à l’exécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d’interfaces en C++Conversion dynamique et RTTIRécapitulatif - Calculateur de formes3Constructeurs et destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d’initialisation des constructeursConstructeurs déléguésApprofondissement des destructeursRègle des trois / cinq / zéroRécapitulatif - Classe String6Surcharge des opérateurs
Introduction à la surcharge des opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l’opérateur d’affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif – Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation des templatesTemplates variadiquesBases de SFINAE et des traits de typesRécapitulatif - Conteneur génériqueEntraînez-vous par vous-même : Compilateur C++ en ligne