Utiliser les composants de la STL en C++

C++Beginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous apprendrez à utiliser diverses composantes de la Bibliothèque Standard de Modèles (Standard Template Library - STL) en C++ pour créer et manipuler des structures de données telles que les vecteurs, les listes, les cartes (maps), les ensembles (sets), etc. Vous explorerez les opérations de base de ces conteneurs STL, notamment l'ajout, la suppression et l'itération sur les éléments. De plus, vous découvrirez comment exploiter les algorithmes STL pour trier, rechercher et traiter des données au sein de ces conteneurs. À la fin de ce laboratoire, vous aurez une solide compréhension de la manière d'exploiter la puissance et la flexibilité de la STL en C++ pour construire des applications efficaces et robustes.

Créer et manipuler un conteneur vecteur

Dans cette étape, vous allez apprendre à propos du conteneur vector de la Bibliothèque Standard de Modèles (Standard Template Library - STL) en C++, qui est un tableau dynamique dont la taille peut augmenter ou diminuer. Les vecteurs sont incroyablement utiles pour stocker et manipuler des collections d'éléments.

Tout d'abord, ouvrez le WebIDE et créez un nouveau fichier appelé vector_demo.cpp dans le répertoire ~/project. Nous allons explorer les opérations de base des vecteurs étape par étape.

touch ~/project/vector_demo.cpp

Ajoutez le code suivant au fichier vector_demo.cpp :

#include <iostream>
#include <vector>

int main() {
    // Create an empty vector of integers
    std::vector<int> numbers;

    // Add elements to the vector using push_back()
    numbers.push_back(10);
    numbers.push_back(20);
    numbers.push_back(30);

    // Print the size of the vector
    std::cout << "Vector size: " << numbers.size() << std::endl;

    // Access elements using index
    std::cout << "First element: " << numbers[0] << std::endl;
    std::cout << "Second element: " << numbers[1] << std::endl;

    // Iterate through the vector using a range-based for loop
    std::cout << "All elements: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Remove the last element
    numbers.pop_back();

    // Check the new size after removing an element
    std::cout << "Vector size after pop_back(): " << numbers.size() << std::endl;

    return 0;
}

Compilez et exécutez le programme :

g++ vector_demo.cpp -o vector_demo
./vector_demo

Exemple de sortie :

Vector size: 3
First element: 10
Second element: 20
All elements: 10 20 30
Vector size after pop_back(): 2

Points clés concernant les vecteurs :

  • Utilisez #include <vector> pour inclure la bibliothèque vector
  • std::vector<type> crée un vecteur d'un type spécifique
  • push_back() ajoute des éléments à la fin du vecteur
  • size() retourne le nombre d'éléments
  • Accédez aux éléments en utilisant l'index []
  • pop_back() supprime le dernier élément
  • La boucle for basée sur une plage est un moyen simple d'itérer sur les vecteurs

Utiliser la liste pour les opérations sur les listes chaînées

Dans cette étape, vous allez apprendre à propos du conteneur list de la STL (Standard Template Library) en C++, qui implémente une liste doublement chaînée. Les listes offrent des opérations d'insertion et de suppression efficaces à n'importe quelle position dans le conteneur.

Ouvrez le WebIDE et créez un nouveau fichier appelé list_demo.cpp dans le répertoire ~/project :

touch ~/project/list_demo.cpp

Ajoutez le code suivant au fichier list_demo.cpp :

#include <iostream>
#include <list>

int main() {
    // Create an empty list of integers
    std::list<int> numbers;

    // Add elements to the list
    numbers.push_back(10);    // Add to the end
    numbers.push_front(5);    // Add to the beginning
    numbers.push_back(20);

    // Print the list size
    std::cout << "List size: " << numbers.size() << std::endl;

    // Iterate through the list
    std::cout << "List elements: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Remove elements
    numbers.pop_front();  // Remove first element
    numbers.pop_back();   // Remove last element

    // Insert an element at a specific position
    auto it = numbers.begin();
    numbers.insert(it, 15);

    // Print updated list
    std::cout << "Updated list: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Check if list is empty
    std::cout << "Is list empty? "
              << (numbers.empty()? "Yes" : "No") << std::endl;

    return 0;
}

Compilez et exécutez le programme :

g++ list_demo.cpp -o list_demo
./list_demo

Exemple de sortie :

List size: 3
List elements: 5 10 20
Updated list: 15 10
Is list empty? No

Points clés concernant les listes :

  • Utilisez #include <list> pour inclure la bibliothèque list
  • push_back() ajoute des éléments à la fin
  • push_front() ajoute des éléments au début
  • pop_front() et pop_back() suppriment des éléments
  • insert() permet d'ajouter des éléments à une position spécifique
  • begin() retourne un itérateur vers le premier élément
  • empty() vérifie si la liste est vide

Implémenter des paires clé-valeur avec une carte (map)

Dans cette étape, vous allez apprendre à propos du conteneur map de la STL (Standard Template Library) en C++, qui stocke des paires clé-valeur dans un ordre de clés trié et unique. Les maps sont utiles pour créer des dictionnaires ou des tableaux associatifs.

Ouvrez le WebIDE et créez un nouveau fichier appelé map_demo.cpp dans le répertoire ~/project :

touch ~/project/map_demo.cpp

Ajoutez le code suivant au fichier map_demo.cpp :

#include <iostream>
#include <map>
#include <string>

int main() {
    // Create a map to store student names and their ages
    std::map<std::string, int> students;

    // Insert key-value pairs
    students["Alice"] = 20;
    students["Bob"] = 22;
    students["Charlie"] = 21;

    // Access values using keys
    std::cout << "Alice's age: " << students["Alice"] << std::endl;

    // Check if a key exists
    if (students.count("David") == 0) {
        std::cout << "David is not in the map" << std::endl;
    }

    // Iterate through the map
    std::cout << "All students:" << std::endl;
    for (const auto& student : students) {
        std::cout << student.first << ": " << student.second << std::endl;
    }

    // Remove a key-value pair
    students.erase("Bob");

    // Check the size of the map
    std::cout << "Number of students: " << students.size() << std::endl;

    return 0;
}

Compilez et exécutez le programme :

g++ map_demo.cpp -o map_demo
./map_demo

Exemple de sortie :

Alice's age: 20
David is not in the map
All students:
Alice: 20
Bob: 22
Charlie: 21
Number of students: 2

Points clés concernant les maps :

  • Utilisez #include <map> pour inclure la bibliothèque map
  • map<KeyType, ValueType> crée une map avec des types de clés et de valeurs spécifiés
  • Accédez aux valeurs en utilisant les crochets []
  • count() vérifie si une clé existe
  • Parcourez les maps à l'aide d'une boucle for basée sur une plage
  • erase() supprime une paire clé-valeur
  • size() retourne le nombre d'éléments

Stocker des éléments uniques en utilisant un ensemble (set)

Dans cette étape, vous allez apprendre à propos du conteneur set de la STL (Standard Template Library) en C++, qui stocke des éléments uniques dans un ordre trié. Les sets empêchent automatiquement les valeurs en double et maintiennent les éléments dans un ordre spécifique.

Ouvrez le WebIDE et créez un nouveau fichier appelé set_demo.cpp dans le répertoire ~/project :

touch ~/project/set_demo.cpp

Ajoutez le code suivant au fichier set_demo.cpp :

#include <iostream>
#include <set>

int main() {
    // Create a set of integers
    std::set<int> numbers;

    // Insert elements
    numbers.insert(10);
    numbers.insert(20);
    numbers.insert(30);
    numbers.insert(10);  // Duplicate, will not be added

    // Print the size of the set
    std::cout << "Set size: " << numbers.size() << std::endl;

    // Iterate through the set
    std::cout << "Set elements: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Check if an element exists
    if (numbers.count(20) > 0) {
        std::cout << "20 is in the set" << std::endl;
    }

    // Remove an element
    numbers.erase(20);

    // Check the size after removal
    std::cout << "Set size after removal: " << numbers.size() << std::endl;

    // Clear the set
    numbers.clear();

    // Check if the set is empty
    std::cout << "Is set empty? "
              << (numbers.empty()? "Yes" : "No") << std::endl;

    return 0;
}

Compilez et exécutez le programme :

g++ set_demo.cpp -o set_demo
./set_demo

Exemple de sortie :

Set size: 3
Set elements: 10 20 30
20 is in the set
Set size after removal: 2
Is set empty? Yes

Points clés concernant les sets :

  • Utilisez #include <set> pour inclure la bibliothèque set
  • set<type> crée un set d'éléments uniques
  • insert() ajoute des éléments (les doublons sont ignorés)
  • count() vérifie l'existence d'un élément
  • erase() supprime un élément
  • clear() supprime tous les éléments
  • empty() vérifie si le set est vide
  • Les éléments sont triés automatiquement

Trier des éléments avec l'algorithme de tri STL

Dans cette étape, vous allez apprendre à utiliser l'algorithme de tri de la STL (Standard Template Library) pour organiser les éléments dans un ordre croissant ou décroissant. La bibliothèque <algorithm> offre des capacités de tri puissantes pour différents conteneurs.

Ouvrez le WebIDE et créez un nouveau fichier appelé sort_demo.cpp dans le répertoire ~/project :

touch ~/project/sort_demo.cpp

Ajoutez le code suivant au fichier sort_demo.cpp :

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // Create a vector of integers
    std::vector<int> numbers = {5, 2, 8, 1, 9, 3};

    // Print original vector
    std::cout << "Original vector: ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Sort the vector in ascending order
    std::sort(numbers.begin(), numbers.end());

    // Print sorted vector
    std::cout << "Sorted vector (ascending): ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Sort the vector in descending order
    std::sort(numbers.begin(), numbers.end(), std::greater<int>());

    // Print vector sorted in descending order
    std::cout << "Sorted vector (descending): ";
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

Compilez et exécutez le programme :

g++ sort_demo.cpp -o sort_demo
./sort_demo

Exemple de sortie :

Original vector: 5 2 8 1 9 3
Sorted vector (ascending): 1 2 3 5 8 9
Sorted vector (descending): 9 8 5 3 2 1

Points clés concernant le tri de la STL :

  • Incluez la bibliothèque <algorithm> pour le tri
  • std::sort() fonctionne avec différents conteneurs
  • Le tri par défaut est en ordre croissant
  • std::greater<type>() trie en ordre décroissant
  • Le tri est effectué sur place, modifiant le conteneur d'origine
  • Fonctionne efficacement avec différents types de conteneurs

Rechercher des éléments en utilisant les algorithmes STL

Dans cette étape, vous allez apprendre à utiliser les algorithmes de la STL (Standard Template Library) pour trouver et rechercher des éléments dans des conteneurs. La bibliothèque <algorithm> propose des fonctions puissantes pour la recherche et la localisation d'éléments.

Ouvrez le WebIDE et créez un nouveau fichier appelé find_demo.cpp dans le répertoire ~/project :

touch ~/project/find_demo.cpp

Ajoutez le code suivant au fichier find_demo.cpp :

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // Create a vector of integers
    std::vector<int> numbers = {5, 2, 8, 1, 9, 3, 8};

    // Find first occurrence of a specific element
    auto it = std::find(numbers.begin(), numbers.end(), 8);
    if (it!= numbers.end()) {
        std::cout << "First occurrence of 8 at index: "
                  << std::distance(numbers.begin(), it) << std::endl;
    }

    // Count occurrences of an element
    int count = std::count(numbers.begin(), numbers.end(), 8);
    std::cout << "Number of 8s in the vector: " << count << std::endl;

    // Find if any element is greater than 6
    bool has_large_element = std::any_of(numbers.begin(), numbers.end(),
        [](int n) { return n > 6; });
    std::cout << "Vector has element > 6: "
              << (has_large_element? "Yes" : "No") << std::endl;

    // Find the minimum and maximum elements
    auto min_it = std::min_element(numbers.begin(), numbers.end());
    auto max_it = std::max_element(numbers.begin(), numbers.end());

    std::cout << "Minimum element: " << *min_it << std::endl;
    std::cout << "Maximum element: " << *max_it << std::endl;

    return 0;
}

Compilez et exécutez le programme :

g++ find_demo.cpp -o find_demo
./find_demo

Exemple de sortie :

First occurrence of 8 at index: 2
Number of 8s in the vector: 2
Vector has element > 6: Yes
Minimum element: 1
Maximum element: 9

Points clés concernant les algorithmes de recherche de la STL :

  • std::find() localise la première occurrence d'un élément
  • std::count() compte le nombre d'occurrences d'un élément
  • std::any_of() vérifie si au moins un élément répond à une condition
  • std::min_element() et std::max_element() trouvent les valeurs extrêmes
  • Les fonctions lambda peuvent être utilisées pour des conditions de recherche personnalisées
  • Les itérateurs de retour pointent vers les éléments trouvés

Parcourir les conteneurs

Dans cette étape, vous allez apprendre différentes façons de parcourir les conteneurs de la STL (Standard Template Library) en utilisant diverses techniques d'itération. Nous allons explorer les boucles for basées sur des plages, les itérateurs et l'itération traditionnelle basée sur des indices.

Ouvrez le WebIDE et créez un nouveau fichier appelé iteration_demo.cpp dans le répertoire ~/project :

touch ~/project/iteration_demo.cpp

Ajoutez le code suivant au fichier iteration_demo.cpp :

#include <iostream>
#include <vector>
#include <list>
#include <map>

int main() {
    // Vector iteration
    std::vector<int> numbers = {10, 20, 30, 40, 50};

    // Method 1: Range-based for loop (most modern and readable)
    std::cout << "Vector iteration (range-based for):" << std::endl;
    for (int num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // Method 2: Iterator-based iteration
    std::cout << "Vector iteration (iterators):" << std::endl;
    for (auto it = numbers.begin(); it!= numbers.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // Method 3: Index-based iteration
    std::cout << "Vector iteration (index-based):" << std::endl;
    for (size_t i = 0; i < numbers.size(); ++i) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    // Map iteration
    std::map<std::string, int> ages = {
        {"Alice", 25},
        {"Bob", 30},
        {"Charlie", 35}
    };

    std::cout << "Map iteration:" << std::endl;
    for (const auto& pair : ages) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

Compilez et exécutez le programme :

g++ iteration_demo.cpp -o iteration_demo
./iteration_demo

Exemple de sortie :

Vector iteration (range-based for):
10 20 30 40 50
Vector iteration (iterators):
10 20 30 40 50
Vector iteration (index-based):
10 20 30 40 50
Map iteration:
Alice: 25
Bob: 30
Charlie: 35

Points clés concernant le parcours des conteneurs :

  • Les boucles for basées sur des plages sont les plus modernes et les plus lisibles
  • Les itérateurs offrent un contrôle précis sur le parcours des conteneurs
  • L'itération basée sur des indices fonctionne bien avec les conteneurs à accès aléatoire
  • Le mot-clé auto facilite l'inférence de type
  • Différents conteneurs prennent en charge différentes méthodes d'itération

Utiliser la pile (stack) et la file d'attente (queue) de la STL

Dans cette étape, vous allez apprendre à connaître deux adaptateurs de conteneurs importants de la STL (Standard Template Library) : la pile (stack) et la file d'attente (queue). Ces conteneurs offrent des opérations spécialisées pour la gestion des données selon le principe « dernier entré, premier sorti » (LIFO - Last In, First Out) et « premier entré, premier sorti » (FIFO - First In, First Out).

Ouvrez le WebIDE et créez un nouveau fichier appelé stack_queue_demo.cpp dans le répertoire ~/project :

touch ~/project/stack_queue_demo.cpp

Ajoutez le code suivant au fichier stack_queue_demo.cpp :

#include <iostream>
#include <stack>
#include <queue>

int main() {
    // Stack demonstration
    std::stack<int> myStack;

    // Push elements onto the stack
    myStack.push(10);
    myStack.push(20);
    myStack.push(30);

    std::cout << "Stack operations:" << std::endl;
    std::cout << "Top element: " << myStack.top() << std::endl;

    // Remove top element
    myStack.pop();
    std::cout << "Top element after pop: " << myStack.top() << std::endl;
    std::cout << "Stack size: " << myStack.size() << std::endl;

    // Queue demonstration
    std::queue<std::string> myQueue;

    // Add elements to the queue
    myQueue.push("Alice");
    myQueue.push("Bob");
    myQueue.push("Charlie");

    std::cout << "\nQueue operations:" << std::endl;
    std::cout << "Front element: " << myQueue.front() << std::endl;
    std::cout << "Back element: " << myQueue.back() << std::endl;

    // Remove front element
    myQueue.pop();
    std::cout << "Front element after pop: " << myQueue.front() << std::endl;
    std::cout << "Queue size: " << myQueue.size() << std::endl;

    return 0;
}

Compilez et exécutez le programme :

g++ stack_queue_demo.cpp -o stack_queue_demo
./stack_queue_demo

Exemple de sortie :

Stack operations:
Top element: 30
Top element after pop: 20
Stack size: 2

Queue operations:
Front element: Alice
Back element: Charlie
Front element after pop: Bob
Queue size: 2

Points clés concernant les piles et les files d'attente :

  • Pile (LIFO - Last In, First Out)
    • push() ajoute un élément au sommet
    • pop() supprime l'élément au sommet
    • top() retourne l'élément au sommet
  • File d'attente (FIFO - First In, First Out)
    • push() ajoute un élément à la fin
    • pop() supprime l'élément au début
    • front() retourne le premier élément
    • back() retourne le dernier élément
  • Les deux ont une méthode size() pour vérifier le nombre d'éléments
  • Incluez les en-têtes <stack> et <queue>

Gérer la sécurité vis-à-vis des exceptions des conteneurs

Dans cette étape, vous allez apprendre à gérer les exceptions et à garantir des opérations sûres avec les conteneurs de la STL (Standard Template Library). La gestion des exceptions permet d'éviter les plantages du programme et offre une gestion robuste des erreurs.

Ouvrez le WebIDE et créez un nouveau fichier appelé exception_safety_demo.cpp dans le répertoire ~/project :

touch ~/project/exception_safety_demo.cpp

Ajoutez le code suivant au fichier exception_safety_demo.cpp :

#include <iostream>
#include <vector>
#include <stdexcept>

void demonstrateVectorSafety() {
    std::vector<int> numbers;

    try {
        // Attempt to access an element from an empty vector
        std::cout << "Attempting to access element from empty vector:" << std::endl;
        numbers.at(0);  // This will throw an out_of_range exception
    }
    catch (const std::out_of_range& e) {
        std::cout << "Out of Range Error: " << e.what() << std::endl;
    }

    // Safe element addition
    try {
        numbers.push_back(10);
        numbers.push_back(20);
        std::cout << "Vector size: " << numbers.size() << std::endl;

        // Safe element access
        std::cout << "First element: " << numbers.at(0) << std::endl;
        std::cout << "Second element: " << numbers.at(1) << std::endl;
    }
    catch (const std::exception& e) {
        std::cout << "An error occurred: " << e.what() << std::endl;
    }
}

int main() {
    // Demonstrate vector exception safety
    demonstrateVectorSafety();

    return 0;
}

Compilez et exécutez le programme :

g++ exception_safety_demo.cpp -o exception_safety_demo
./exception_safety_demo

Exemple de sortie :

Attempting to access element from empty vector:
Out of Range Error: vector
Vector size: 2
First element: 10
Second element: 20

Points clés concernant la sécurité vis-à-vis des exceptions des conteneurs :

  • Utilisez des blocs try-catch pour gérer les exceptions potentielles
  • std::out_of_range est lancée lorsqu'on accède à des éléments invalides d'un vecteur
  • La méthode at() effectue une vérification des limites, contrairement à l'opérateur []
  • Attrapez d'abord les exceptions spécifiques, puis les plus générales
  • Toujours gérer les exceptions potentielles pour éviter les plantages du programme
  • Utilisez les classes d'exceptions standard de <stdexcept>

Résumé

Dans ce laboratoire, vous avez appris à connaître diverses composantes de la Bibliothèque Standard de Modèles (Standard Template Library - STL) en C++ et à les utiliser efficacement. Vous avez commencé par explorer le conteneur vector, qui est un tableau dynamique dont la taille peut augmenter ou diminuer. Vous avez appris à ajouter et à supprimer des éléments, à y accéder à l'aide d'indices et à parcourir le vecteur à l'aide d'une boucle for basée sur une plage.

Ensuite, vous avez approfondi votre connaissance du conteneur list, qui est une implémentation de liste doublement chaînée. Vous avez découvert comment effectuer des opérations courantes sur les listes chaînées telles que l'insertion, la suppression et le parcours d'éléments. Vous avez également exploré le conteneur map, qui vous permet de stocker des paires clé-valeur, et le conteneur set, qui stocke des éléments uniques. De plus, vous avez appris à utiliser des algorithmes de la STL tels que sort et find pour manipuler et rechercher des éléments dans ces conteneurs. Enfin, vous avez exploré les conteneurs stack et queue, et discuté de l'importance de la sécurité vis-à-vis des exceptions lors de l'utilisation des composantes de la STL.