std::lexicographical_compare în C++

Compară două intervale ca în dicționar și spune dacă primul vine înaintea celui de-al doilea.

Sintaxă
bool lexicographical_compare(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2);

Ce face std::lexicographical_compare

Compararea lexicografică funcționează ca ordinea cuvintelor în dicționar: se compară primele elemente; dacă sunt egale, următoarele și așa mai departe. Primul element diferit decide. Dacă un interval este prefixul celuilalt, cel mai scurt este „mai mic”.

Așa compară deja operatorul < pentru std::string, std::vector sau std::array. Funcția este utilă pentru intervale de tipuri diferite sau cu un criteriu propriu, de exemplu fără majuscule.

Parametri

Parametru Descriere
first1, last1 Primul interval.
first2, last2 Al doilea interval.
comp Opțional. Criteriul de comparare a elementelor.

Ce returnează

true dacă primul interval este strict mai mic decât al doilea.

Exemple

Exemplul 1: Versiuni de program

#include <algorithm>
#include <print>
#include <vector>

int main() {
    std::vector<int> v1{2, 4, 1};
    std::vector<int> v2{2, 10, 0};

    bool mai_vechi = std::lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end());
    std::println("2.4.1 este mai veche decât 2.10.0: {}", mai_vechi);

    std::vector<int> v3{2, 4};
    std::println("2.4 < 2.4.1: {}", std::ranges::lexicographical_compare(v3, v1));
}

Rezultat

2.4.1 este mai veche decât 2.10.0: true
2.4 < 2.4.1: true

Exemplul 2: Comparare fără majuscule

Cu operatorul <, „ana” nu este înaintea lui „Bianca”: literele mari au coduri mai mici decât cele mici (‘B’ este 66, ‘a’ este 97). Comparatorul care transformă în litere mici rezolvă problema.

#include <algorithm>
#include <cctype>
#include <print>
#include <string>

int main() {
    std::string a = "ana";
    std::string b = "Bianca";

    auto fara_majuscule = [](unsigned char x, unsigned char y) { return std::tolower(x) < std::tolower(y); };

    std::println("Cu majuscule: {}", a < b);
    std::println("Fără majuscule: {}", std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), fara_majuscule));
}

Rezultat

Cu majuscule: false
Fără majuscule: true

Greșeli frecvente

  • Compari versiuni ca text ("2.10" < "2.4" dă true, pentru că ‘1’ < ‘4’). Transformă-le în numere și compară vectorii de numere.

Comenzi înrudite

  • std::equal: Verifică dacă două intervale conțin aceleași elemente, în aceeași ordine.
  • std::mismatch: Găsește prima poziție unde două intervale diferă și returnează iteratorii din ambele.
  • std::sort: Sortează elementele dintr-un interval, crescător sau după o regulă dată de tine.