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ștem.contains(cheie)(C++20) saum.find(cheie) != m.end(). - Folosești
m[cheie]pe un mapconst(de exemplu un parametruconst std::map<...>&). Nu compilează, pentru căoperator[]poate modifica map-ul; foloseșteatsaufind. - Încerci să schimbi cheia prin iterator (
it->first = ...). Cheia esteconst; scoate elementul cuextract, 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ă.