pair — două valori legate într-una

Bază~14 min15 pași

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.first16;
  • p.second"Ana";
  • p.first = 17; → acum perechea e (17, "Ana").
Observația-cheie

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
După sort: grupate crescător după first; la first egal, crescător după second.

Complexitate

OperațieTimp
Acces .first / .secondO(1)
Comparație a două perechiO(1) pentru tipuri simple
sort pe vector<pair> cu n elementeO(n log n)
Greșeli frecvente

Greșeli frecvente de concurs:

  • Crezi că first e o funcție: e câmp, scrii p.first, NU p.first().
  • Ordinea criteriilor inversată: dacă vrei sortare după notă, pune nota în first, nu în second. Comparația privește întâi first.
  • Sortare descrescătoare greșită: sort implicit e crescător pe ambele câmpuri. Pentru „notă descrescător” ai nevoie de comparator sau de un truc (ex. negarea valorii din first).
  • tie cu număr greșit de variabile: tie(a, b) trebuie să aibă exact două variabile pentru un pair, altfel nu compilează.

Recapitulare

  • pair leagă două valori (.first, .second); creezi cu {a, b} sau make_pair(a, b).
  • Comparația e lexicografică (întâi first, apoi second) — ideal pentru sortare după 2 criterii fără comparator.
  • Despachetezi rapid cu tie(a, b) = p; sau auto [a, b] = p;.

Întrebarea 1 / 3

Ai vector<pair<int,int>> și apelezi sort fără comparator. Cum se ordonează perechile?