std::map în C++

Dicționar ordonat: asociază fiecărei chei unice o valoare și păstrează cheile sortate.

Sintaxă
#include <map>

std::map<Cheie, Valoare> nume;
std::map<Cheie, Valoare> nume{{cheie1, valoare1}, {cheie2, valoare2}};

Ce face std::map

std::map ține perechi cheie-valoare, de exemplu nume de produs și preț. Fiecare cheie apare o singură dată, iar perechile sunt păstrate sortate după cheie (crescător, cu <). Căutarea, adăugarea și ștergerea durează O(log n): la un milion de chei, cam 20 de comparații.

m[cheie] returnează valoarea pentru cheie. Atenție: dacă cheia nu există, operator[] o adaugă, cu o valoare implicită (0, text gol). Ca să verifici fără să adaugi, folosește contains, find sau count; ca să citești cu eroare clară, folosește at.

Parcurgerea dă perechile în ordinea cheilor. Fiecare element este un std::pair<const Cheie, Valoare>: .first este cheia, .second valoarea; cu auto& [cheie, valoare] le despachetezi direct. Iteratorii unui map rămân valizi la inserări; se invalidează doar cei la elementul șters. Dacă nu ai nevoie de ordine, std::unordered_map este de obicei mai rapid.

Parametri

Parametru Descriere
Cheie Tipul cheilor; trebuie să poată fi comparat cu < (sau dai un comparator ca al treilea parametru).
Valoare Tipul valorilor asociate.

Ce returnează

Un obiect map. m[cheie] returnează o referință la valoare (creând-o dacă lipsește).

Exemple

Exemplul 1: Prețuri, sortate automat după nume

#include <map>
#include <print>
#include <string>

int main() {
    std::map<std::string, double> preturi{{"pâine", 4.5}, {"lapte", 6.2}};
    preturi["cafea"] = 23.9;          // adaugă o pereche nouă
    preturi["lapte"] = 6.5;           // modifică una existentă

    for (const auto& [produs, pret] : preturi) {
        std::println("{:<6} {:>5.2f} lei", produs, pret);
    }
    std::println("{}", preturi);
}

Rezultat

cafea  23.90 lei
lapte   6.50 lei
pâine   4.50 lei
{"cafea": 23.9, "lapte": 6.5, "pâine": 4.5}

Exemplul 2: Numărarea cuvintelor

Aici faptul că operator[] creează cheia cu valoarea 0 este exact ce vrem: ++ pornește de la 0.

#include <map>
#include <print>
#include <sstream>
#include <string>

int main() {
    std::istringstream text("ana are mere ana are pere ion are mere");
    std::map<std::string, int> frecventa;
    std::string cuvant;
    while (text >> cuvant) {
        ++frecventa[cuvant];
    }
    for (const auto& [c, n] : frecventa) {
        std::println("{}: {}", c, n);
    }
}

Rezultat

ana: 2
are: 3
ion: 1
mere: 2
pere: 1

Exemplul 3: Capcana: operator[] adaugă chei

#include <map>
#include <print>
#include <string>

int main() {
    std::map<std::string, int> stoc{{"mere", 10}};
    if (stoc["pere"] == 0) {                    // creează "pere" cu 0!
        std::println("Nu avem pere.");
    }
    std::println("Chei după verificarea greșită: {}", stoc.size());

    if (!stoc.contains("prune")) {              // nu adaugă nimic
        std::println("Nu avem prune.");
    }
    std::println("Chei după verificarea corectă: {}", stoc.size());
}

Rezultat

Nu avem pere.
Chei după verificarea greșită: 2
Nu avem prune.
Chei după verificarea corectă: 2

Greșeli frecvente

  • Verifici existența unei chei cu if (m[cheie]). Expresia adaugă cheia dacă lipsește și umple map-ul cu intrări goale. Folosește m.contains(cheie) (C++20) sau m.find(cheie) != m.end().
  • Folosești m[cheie] pe un map const (de exemplu un parametru const std::map<...>&). Nu compilează, pentru că operator[] poate modifica map-ul; folosește at sau find.
  • Încerci să schimbi cheia prin iterator (it->first = ...). Cheia este const; scoate elementul cu extract, schimbă-i cheia și pune-l la loc.

Comenzi înrudite

  • std::map::insert: Adaugă o pereche cheie-valoare doar dacă cheia nu există; spune prin rezultat dacă a adăugat-o.
  • std::map::find: find() caută o cheie și returnează un iterator la ea sau end(); count() și contains() spun doar dacă există.
  • std::map::at: Returnează valoarea unei chei existente; aruncă std::out_of_range dacă cheia nu există, fără să o adauge.
  • std::map::erase: Șterge din map o cheie (cu valoarea ei), elementul indicat de un iterator sau un interval.
  • std::unordered_map: Dicționar bazat pe tabelă hash: căutare în timp mediu constant, dar fără o ordine anume a elementelor.
  • std::multimap: Ca std::map, dar aceeași cheie poate apărea de mai multe ori, cu valori diferite.
  • std::flat_map: Dicționar ordonat ca std::map, dar ținut în doi vectori sortați: căutare și parcurgere rapide, inserare mai lentă.