De ce contează?
Pe un bilet de tren ai două informații care merg împreună: vagonul și locul.
Nu le ții pe foi separate — sunt scrise pe același bilet, una lângă alta. Când
ai nevoie de o pereche de valori care nu se despart niciodată, folosești pair.
Ce este un pair?
Un pair (din <utility>) este o cutie cu exact două valori lipite
împreună într-un singur obiect. Le accesezi prin .first (prima) și
.second (a doua). Tipurile pot fi diferite: pair<int, string> ține un număr
și un șir.
De ce să le legi? Pentru că deseori două date au sens doar împreună:
coordonate (x, y), o muchie (nod, cost), o pereche (notă, nume). În loc să
ții doi vectori paraleli și să-i sincronizezi manual, ții un singur
vector<pair<...>> și nu mai poți încurca corespondența.
Cum funcționează, pas cu pas
Construim o pereche care leagă vârsta de nume și citim cele două câmpuri:
pair<int, string> p;→ pereche goală;p = make_pair(16, "Ana");→first = 16,second = "Ana";p.first→16;p.second→"Ana";p.first = 17;→ acum perechea e(17, "Ana").
first și second sunt câmpuri obișnuite, nu funcții: scrii p.first, fără
paranteze. Le poți și modifica după ce ai creat perechea, exact ca pe orice
variabilă.
Implementare C++
#include <iostream>
#include <utility>
#include <string>
using namespace std;
int main() {
pair<int, string> p = make_pair(16, "Ana");
cout << p.first << " " << p.second << "\n"; // 16 Ana
p.first = 17; // modificam primul camp
cout << p.first << "\n"; // 17
// initializare directa cu acolade, fara make_pair
pair<int, int> q = {3, 8};
cout << q.first + q.second << "\n"; // 11
// despachetare: tie sau structured bindings (C++17)
int a, b;
tie(a, b) = q; // a=3, b=8
auto [x, y] = q; // x=3, y=8
cout << a << " " << b << " " << x << " " << y << "\n"; // 3 8 3 8
return 0;
}Comparație lexicografică și sortarea după 2 criterii
Două perechi se compară lexicografic: întâi după first; dacă first sunt
egale, abia atunci după second. Asta îl face perfect pentru ordonarea după
două criterii — pui criteriul principal în first și departajarea în second.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// perechi (nota, varsta): sortam dupa nota, apoi dupa varsta
vector<pair<int, int>> v = {{9, 16}, {7, 15}, {9, 14}, {7, 17}};
sort(v.begin(), v.end()); // foloseste comparatia implicita a lui pair
for (auto p : v) {
cout << p.first << "," << p.second << " ";
}
cout << "\n";
// 7,15 7,17 9,14 9,16
return 0;
}Observă rezultatul: întâi toate perechile cu first = 7 (ordonate între ele
după second), apoi cele cu first = 9. Nu ai scris niciun comparator —
sort folosește comparația gata-făcută a lui pair.
| (first|second) | 7|15 | 7|17 | 9|14 | 9|16 |
Complexitate
| Operație | Timp |
|---|---|
Acces .first / .second | O(1) |
| Comparație a două perechi | O(1) pentru tipuri simple |
sort pe vector<pair> cu n elemente | O(n log n) |
Greșeli frecvente de concurs:
- Crezi că
firste o funcție: e câmp, scriip.first, NUp.first(). - Ordinea criteriilor inversată: dacă vrei sortare după notă, pune nota în
first, nu însecond. Comparația privește întâifirst. - Sortare descrescătoare greșită:
sortimplicit e crescător pe ambele câmpuri. Pentru „notă descrescător” ai nevoie de comparator sau de un truc (ex. negarea valorii dinfirst). tiecu număr greșit de variabile:tie(a, b)trebuie să aibă exact două variabile pentru unpair, altfel nu compilează.
Recapitulare
pairleagă două valori (.first,.second); creezi cu{a, b}saumake_pair(a, b).- Comparația e lexicografică (întâi
first, apoisecond) — ideal pentru sortare după 2 criterii fără comparator. - Despachetezi rapid cu
tie(a, b) = p;sauauto [a, b] = p;.