Les dictionnaires en C++ : Classe map (Bibliothèque STL)

16 Feb 2022 16 Feb 2022 7799 vues ESSADDOUKI Mostafa 10 min de lecture
Introduction et syntaxe de base
1 Introduction au langage C++ 2 Entrée-sortie en C++ - cin et cout 3 Inférence de type avec le mot-clé auto en C++ 4 Classe std::string et les chaînes de caractères en C++ 5 Les structures conditionnelles (if et switch) en C++ (C++17 et C++20) 6 Les boucles en C++ (C++17 et C++20) 7 La gestion des fichiers en C++
Pointeurs et fonctions
8 Introduction aux pointeurs en C++ - Déclaration et interêts 9 Les références en C++ - déclaration et interêts 10 Les tableaux en C++ - Déclaration et interêts 11 Introduction aux fonctions en C++ 12 Passer des arguments à une fonction en C++ 13 Déclarer un paramètre const en C++ 14 Les fonctions Lambda en C++ 15 Fonctions utiles (Mathématiques et caractères) en C++
Programmation OO
16 Classes et objets en C++ 17 Spécificateurs d'accès en C++ 18 Constructeurs et destructeur d'une classe en C++ 19 Fonctions membres en C++ 20 Membres statiques d'une classe en C++ 21 Fonctions en ligne en C++ - inline 22 Fonctions et classes amies en C++ - friend 23 Surcharge des fonctions en C++ 24 Surcharge des opérateurs en C++ 25 Héritage en C++ 26 La gestion d'exceptions en C++ : déclaration, utilisation et personnalisation 27 fonctions et classes templates en C++ 28 Les nouveautés C++20 pour améliorer les templates en C++
Structures de données
29 Introduction aux structures de données 30 Les structures en C++ et la différence avec les structures en C 31 Les listes chaînées en C++ 32 Les piles en C++ 33 File d'attente en C++ 34 Arbre binaire de recherche : définition et mise en oeuvre en C++
La bibliothèque standard (STL)
35 Introduction à la bibliothèque de Template Standard STL 36 Les itérateurs en C++ - définition, déclaration et exemples 37 La classe array en C++ (bibliothèque STL) <array> 38 La classe vector de la bibliothèque STL <vector> 39 La classe deque en C++ ( Bibliothèque STL) 40 La classe list en C++ (bibliothèque STL) <list> 41 La classe stack (Pile) en C++ (bibliothèque STL) <stack> 42 La classe queue (File d'attente) en C++ (bibliothèque STL) <queue> 43 La file d'attente prioritaire (classe priority_queue) - Bibliothèque STL 44 Les ensembles en C++ (Classe set <set> - Bibliothèque STL) 45 Les dictionnaires en C++ : Classe map (Bibliothèque STL) 46 Introduction aux algorithmes de la bibliothèque STL (programmation compétitive) 47 Tri et méthodes associées en C++ - Bibliothèque STL 48 Recherche dichotomique et méthodes associées en C++ - Bibliothèque STL 49 Appliquer un prédicat ou une fonction aux éléments d'une séquence en C++ - Bibliothèque STL 50 Recherche dans une séquence et méthodes associées en C++ - Bibliothèque STL

La classe map (dictionnaire / tableau associatif)

Définition

La classe map, qui est également appelée dictionnaire ou tableau associatif, est définie dans le fichier d'en-tête <map>.

C'est un conteneur qui stocke une paire de clé et de valeur. Deux valeurs mappées ne peuvent pas partager les mêmes valeurs de clé. Les éléments sont triés par ordre croissant en fonction de la clé. Dans un dictionnaire, les clés sont uniques.

Implémentation

La classe map est implémentée en utilisant des arbres binaires de recherche équilibrés.

En interne, les conteneurs map conservent tous leurs éléments triés. Les éléments sont toujours insérés dans leur position respective en suivant cet ordre.

Structure d'un élément

Les valeurs clés servent à trier et à identifier les éléments de manière unique. Les valeurs mappées servent à stocker le contenu associé à la clé. Les deux peuvent être de types différents, mais le type membre pair les combine.

Syntaxe de déclaration

   
Déclaration d'une map C++
std::map<type_cle, type_valeur> nomMap;
  • type_cle : le type de données des clés (ex: string, int)
  • type_valeur : le type de données des valeurs associées (ex: float, double)
  • nomMap : le nom du dictionnaire

  Exemple n°1

map<string, int> dict1;

Nous avons déclaré ici un dictionnaire nommé dict1. Le dictionnaire aura une chaîne de caractères comme type de données pour les clés et un entier comme type de données pour les valeurs.

Opérations sur les map

Les opérations définies pour la classe map sont très similaires à celles de la classe set. La principale différence est la possibilité d'accéder aux éléments du dictionnaire à l'aide de l'opérateur [ ].

Note sur l'opérateur []

Cet opérateur fait ressembler un objet map à un tableau dans lequel l'index est une valeur clé au lieu d'un entier. En d'autres termes, si nous connaissons la valeur de la clé, nous pouvons accéder à l'élément en utilisant nomMap[clé].

Cependant, l'opérateur [ ] n'agit pas comme celui utilisé pour un tableau ou un vecteur. C'est juste une notation pour créer une paire clé-valeur. Un dictionnaire n'utilise que des itérateurs bidirectionnels et ne peut pas sauter d'une paire à une autre à l'aide de l'opérateur + ou -.

Taille

Il existe trois fonctions membres pour vérifier la taille, la taille maximale et le vide :

SyntaxeDescription
dict1.size();Renvoie la taille actuelle (nombre d'éléments)
dict1.max_size();Renvoie la taille maximale possible
dict1.empty();Renvoie true si le dictionnaire est vide

Accès aux éléments

Opérateur []

Si k correspond à la clé d'un élément du conteneur, la fonction renvoie une référence à sa valeur mappée.

Comportement important

Si k ne correspond à la clé d'aucun élément du conteneur, la fonction insère un nouvel élément avec cette clé et renvoie une référence à sa valeur mappée.

Notez que cette fonction augmente toujours la taille du conteneur de 1, même si aucune valeur mappée n'est assignée à l'élément (l'élément est construit en utilisant son constructeur par défaut).

map::at()

Renvoie une référence à la valeur mappée de l'élément identifié par la clé k.

Différence avec []

Si k ne correspond à la clé d'aucun élément du conteneur, la fonction lève une exception out_of_range au lieu d'insérer un élément.

Insertion

L'insertion étend le conteneur en insérant de nouveaux éléments, augmentant effectivement la taille du conteneur du nombre d'éléments insérés.

Attention à l'unicité des clés

Les clés des éléments d'un dictionnaire étant uniques, l'opération d'insertion vérifie si chaque élément inséré possède une clé équivalente à celle d'un élément déjà présent. Si tel est le cas, l'élément n'est pas inséré et la fonction renvoie un itérateur vers cet élément existant.

Une autre façon d'insérer des éléments dans un dictionnaire est d'utiliser la fonction membre map::operator[].

Insertion d'une paire

iterator map_name.insert({clé, élément});

La fonction accepte une paire composée d'une clé et d'un élément à insérer. Elle renvoie un itérateur pointant vers le nouvel élément (ou vers l'élément existant si la clé était déjà présente).

Insertion avec position indicative

iterator map_name.insert(iterator position, {clé, élément});
  • {clé, élément} : la paire à insérer
  • position : ce paramètre ne spécifie pas la position exacte d'insertion, mais indique une position à partir de laquelle l'opération de recherche doit être lancée pour accélérer le processus.

Insertion d'une plage

iterator map_name.insert(iterator position1, iterator position2);

Cette fonction accepte deux itérateurs position1 et position2 qui spécifient la plage d'éléments [position1, position2] à insérer dans le conteneur.

Itérateurs

La classe map utilise des itérateurs bidirectionnels (et non à accès aléatoire). Elle fournit les mêmes huit itérateurs internes que les conteneurs de séquence :

SyntaxeDescription
dict1.begin()Retourne un itérateur au premier élément
dict1.end()Renvoie un itérateur à l'élément après le dernier
dict1.rbegin()Retourne un itérateur inverse au dernier élément
dict1.rend()Renvoie un itérateur inverse à l'élément avant le premier
dict1.cbegin()Version constante de begin()
dict1.cend()Version constante de end()
dict1.crbegin()Version constante de rbegin()
dict1.crend()Version constante de rend()

Recherche dans un dictionnaire

Comme la classe map utilise un arbre binaire de recherche équilibré, la recherche est possible et efficace (complexité logarithmique).

SyntaxeDescription
dict1.count(k)Renvoie le nombre d'éléments avec la clé k (0 ou 1, car les clés sont uniques)
dict1.find(k)Retourne un itérateur pointant sur l'élément avec la clé k, ou dict1.end() si non trouvé
dict1.lower_bound(k)Renvoie la première position où k peut être inséré (premier élément >= k)
dict1.upper_bound(k)Renvoie la dernière position où k peut être inséré (premier élément > k)
dict1.equal_range(k)Renvoie une paire d'itérateurs [lower_bound, upper_bound] pour la clé k

Suppression d'éléments

La suppression d'éléments peut se faire par clé ou par itérateur.

SyntaxeDescription
dict1.erase(k)Supprime l'élément avec la clé k (renvoie le nombre d'éléments supprimés)
dict1.erase(pos)Supprime l'élément pointé par l'itérateur pos
dict1.erase(premier, dernier)Supprime les éléments dans la plage [premier, dernier)
dict1.clear()Supprime tous les éléments (vide le dictionnaire)

Exemple complet

 Programme d'exemple

Utilisation d'une map

Voici un programme complet illustrant les principales opérations sur une map.

#include <iostream>
#include <map>

using namespace std;

void afficher(map<string, float> dict1)
{
    map<string, float>::iterator it;
    for (it = dict1.begin(); it != dict1.end(); it++)
    {
        cout << it->first << " ";
        cout << it->second << '\n';
    }
    cout << "\n";
}

int main() {
    map<string, float> dict1;

    // Insertion par opérateur []
    dict1["Ismail"] = 10.5;
    dict1["Sara"] = 17.5;
    dict1["Omar"] = 8.5;
    
    // Insertion par la méthode insert
    dict1.insert({"Alex", 14});
    dict1.insert({"Moneim", 10});

    cout << "Nombre d'éléments dans dict1 : " << dict1.size() << '\n';

    cout << "Les éléments du dictionnaire : " << '\n';
    afficher(dict1);

    // Modification d'une valeur (Sara passe de 17.5 à 13.25)
    dict1["Sara"] = 13.25;

    // Suppression d'un élément (Omar)
    dict1.erase("Omar");
    
    cout << "Les éléments après suppression : " << '\n';
    afficher(dict1);

    return 0;
}
Résultat
Nombre d'éléments dans dict1 : 5
Les éléments du dictionnaire :
Alex 14
Ismail 10.5
Moneim 10
Omar 8.5
Sara 17.5

Les éléments après suppression :
Alex 14
Ismail 10.5
Moneim 10
Sara 13.25

Explication de l'exemple :

  • Les éléments sont automatiquement triés par ordre alphabétique des clés (Alex, Ismail, Moneim, Omar, Sara).
  • L'opérateur [] permet d'insérer et de modifier des éléments facilement.
  • La fonction afficher() utilise un itérateur pour parcourir tous les éléments.
  • it->first donne accès à la clé, it->second donne accès à la valeur.
  • erase("Omar") supprime l'élément dont la clé est "Omar".
Points clés à retenir
  • Une map est un conteneur associatif qui stocke des paires (clé, valeur).
  • Les clés sont uniques et triées automatiquement.
  • Implémentation sous-jacente : arbre binaire de recherche équilibré.
  • L'opérateur [] permet l'accès et l'insertion (mais insère un élément si la clé n'existe pas).
  • La méthode at() est similaire mais lève une exception si la clé n'existe pas.
  • Les itérateurs sont bidirectionnels (pas d'accès aléatoire).
  • Recherche efficace : O(log n) pour find, lower_bound, etc.
  • Principales méthodes : insert(), erase(), find(), count(), size(), empty(), clear().
  • Pour parcourir, on utilise it->first (clé) et it->second (valeur).

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.