De ce contează?
Un clasament de fotbal nu se face dintr-o singură regulă: întâi puncte, la egalitate golaveraj, apoi goluri marcate. Fiecare regulă intră în joc doar când cele dinainte n-au departajat. Sortarea după mai multe criterii e exact acest lanț de reguli de rezervă.
Problema
Rar sortezi după un singur criteriu. „Ordonează elevii după medie descrescător, iar la medii egale alfabetic" — două criterii cu priorități diferite. Cum le combini corect?
Soluția curată: un singur comparator
Tratezi criteriile în ordinea priorității. Rezolvi după primul; treci la al doilea numai la egalitate pe primul; la al treilea numai la egalitate pe primele două:
bool cmp(const Elev &a, const Elev &b) {
if (a.media != b.media) return a.media > b.media; // 1) media descrescator
if (a.nume != b.nume) return a.nume < b.nume; // 2) nume crescator
return a.varsta < b.varsta; // 3) ultima departajare
}Tiparul e mereu același: pentru fiecare criteriu, „dacă diferă, decide acum; altfel coboară la următorul". Ultimul criteriu decide fără if, fiindcă nu mai are pe cine să paseze.
De ce ordinea criteriilor contează
Schimbând ordinea, schimbi clasamentul. „Întâi media, apoi numele" e diferit de „întâi numele, apoi media". Pune criteriul cel mai important primul — el domină; restul doar departajează egalitățile.
Alternativa: sortări succesive stabile
Poți obține același rezultat cu mai multe stable_sort, dar în ordine inversă a priorității: întâi după criteriul secundar, apoi după cel principal.
stable_sort(v, v + n, dupaNume); // criteriul secundar intai
stable_sort(v, v + n, dupaMedie); // criteriul principal la finalFuncționează doar cu sortare stabilă: a doua sortare nu strică ordinea după nume la medii egale, fiindcă stabilitatea păstrează ordinea elementelor considerate egale.
Un singur comparator e de obicei mai sigur și mai clar decât sortări succesive. Folosește sortările stabile multiple doar când criteriile sunt greu de combinat într-o singură funcție.
Cum alegi între cele două
| Situație | Alegere |
|---|---|
| criterii simple, cunoscute dinainte | un singur comparator |
| multe criterii sau adăugate dinamic | sortări succesive stabile |
| ai nevoie de viteză maximă | un singur comparator (o singură sortare) |
Capcane la sortarea după mai multe criterii:
- Departajare aplicată mereu: tratezi al doilea criteriu și când primul diferă → ordine greșită. Coboară la criteriul următor numai la egalitate.
- Ordinea inversă la sortări succesive: cu
stable_sortmultiplu, criteriul principal trebuie aplicat ULTIMUL, nu primul. - Folosești
sortîn loc destable_sortla sortări succesive:sortnu e stabil, deci strică ordinea criteriului anterior. <=/>=în comparator: ordinea trebuie strictă; non-strict → comportament nedefinit.
Recapitulare
- Pentru mai multe criterii, un singur comparator: decizi după primul, departajezi la următorul doar la egalitate pe cel anterior.
- Alternativă:
stable_sort-uri succesive în ordinea inversă a priorității (principal la final). - Ordinea criteriilor schimbă rezultatul; preferă un comparator unic pentru claritate și viteză.