Namespaces
Variants

std::lexicographical_compare

С ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы над диапазонами (C++20)
Ограниченные алгоритмы, напр. ranges::copy, ranges::sort, ...
Немодифицирующие операции над последовательностями    
Пакетные операции
(C++17)
Операции поиска
Модифицирующие операции над последовательностями
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(до C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разделения
(C++11)    

Операции сортировки
Операции двоичного поиска
(по разделённым диапазонам)
Операции над множествами (над отсортированными диапазонами)
Операции слияния (над отсортированными диапазонами)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановок


Политики выполнения (C++17)
(только для демонстрации*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Определён в заголовке <algorithm>
template< class InputIt1, class InputIt2 >
bool lexicographical_compare( InputIt1 first1, InputIt1 last1,
                              InputIt2 first2, InputIt2 last2 );
(1) (constexpr начиная с C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2 >
bool lexicographical_compare( ExecutionPolicy&& policy,
                              ForwardIt1 first1, ForwardIt1 last1,
                              ForwardIt2 first2, ForwardIt2 last2 );
(2) (начиная с C++17)
template< class InputIt1, class InputIt2, class Compare >
bool lexicographical_compare( InputIt1 first1, InputIt1 last1,
                              InputIt2 first2, InputIt2 last2,
                              Compare comp );
(3) (constexpr начиная с C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2, class Compare >
bool lexicographical_compare( ExecutionPolicy&& policy,
                              ForwardIt1 first1, ForwardIt1 last1,
                              ForwardIt2 first2, ForwardIt2 last2,
                              Compare comp );
(4) (начиная с C++17)

Проверяет, является ли первый диапазон [first1, last1) лексикографически меньшим, чем второй диапазон [first2, last2).

1) Элементы сравниваются с помощью operator<.
3) Элементы сравниваются с помощью заданной бинарной функции сравнения comp.
2,4) То же, что и (1,3), но выполняется в соответствии с policy. Эти перегрузки участвуют в разрешении перегрузки, только если значение следующего выражения равно true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(начиная с C++20)

Лексикографическое сравнение — это операция со следующими свойствами:

  • Два диапазона сравниваются поэлементно.
  • Первый несовпадающий элемент определяет, какой диапазон лексикографически меньше или больше другого.
  • Если один диапазон является префиксом другого, то более короткий диапазон лексикографически меньше другого.
  • Если два диапазона имеют эквивалентные элементы и одинаковую длину, то диапазоны лексикографически равны.
  • Пустой диапазон лексикографически меньше любого непустого диапазона.
  • Два пустых диапазона лексикографически равны.

Параметры

first1, last1 - пара итераторов, определяющая первый диапазон элементов для проверки
first2, last2 - пара итераторов, определяющая второй диапазон элементов для проверки
policy - политика выполнения для использования
comp - объект функции сравнения (т. е. объект, удовлетворяющий требованиям Compare), который возвращает true, если первый аргумент меньше второго.

Сигнатура функции сравнения должна быть эквивалентна следующей:

bool cmp(const Type1& a, const Type2& b);

Хотя сигнатура не обязательно должна содержать const&, функция не должна изменять переданные ей объекты и должна принимать все значения типа (возможно, const) Type1 и Type2 независимо от категории значения (таким образом, Type1& не разрешено, а также Type1, за исключением случаев, когда Type1 перемещение эквивалентно копированию(начиная с C++11)).
Типы Type1 и Type2 должны быть такими, чтобы объекты типов InputIt1 и InputIt2 можно было разыменовать и затем неявно преобразовать в Type1 и Type2.

Требования к типам
-
InputIt1, InputIt2 должен соответствовать требованиям LegacyInputIterator.
-
ForwardIt1, ForwardIt2 должен соответствовать требованиям LegacyForwardIterator.
-
Compare должен соответствовать требованиям Compare.

Возвращаемое значение

true, если первый диапазон лексикографически меньше второго, иначе false.

Сложность

Задано N1 как std::distance(first1, last1) и N2 как std::distance(first2, last2):

1,2) Не более 2min(1,N2) сравнений с помощью operator<.
3,4) Не более 2min(N1,N2) применений функции сравнения comp.

Исключения

Перегрузки с параметром шаблона с именем ExecutionPolicy сообщают об ошибках следующим образом:

  • Если выполнение функции, вызванной в рамках алгоритма, генерирует исключение и ExecutionPolicy является одной из стандартных политик, вызывается std::terminate. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удаётся выделить память, генерируется std::bad_alloc.

Возможная реализация

lexicographical_compare (1)
template<class InputIt1, class InputIt2>
bool lexicographical_compare(InputIt1 first1, InputIt1 last1,
                             InputIt2 first2, InputIt2 last2)
{
    for (; (first1 != last1) && (first2 != last2); ++first1, (void) ++first2)
    {
        if (*first1 < *first2)
            return true;
        if (*first2 < *first1)
            return false;
    }
    
    return (first1 == last1) && (first2 != last2);
}
lexicographical_compare (3)
template<class InputIt1, class InputIt2, class Compare>
bool lexicographical_compare(InputIt1 first1, InputIt1 last1,
                             InputIt2 first2, InputIt2 last2, Compare comp)
{
    for (; (first1 != last1) && (first2 != last2); ++first1, (void) ++first2)
    {
        if (comp(*first1, *first2))
            return true;
        if (comp(*first2, *first1))
            return false;
    }
    
    return (first1 == last1) && (first2 != last2);
}

Пример

#include <algorithm>
#include <iostream>
#include <random>
#include <vector>

void print(const std::vector<char>& v, auto suffix)
{
    for (char c : v)
        std::cout << c << ' ';
    std::cout << suffix;
}

int main()
{
    std::vector<char> v1{'a', 'b', 'c', 'd'};
    std::vector<char> v2{'a', 'b', 'c', 'd'};
    
    for (std::mt19937 g{std::random_device{}()};
         !std::lexicographical_compare(v1.begin(), v1.end(),
                                       v2.begin(), v2.end());)
    {
        print(v1, ">= ");
        print(v2, '\n');
        
        std::shuffle(v1.begin(), v1.end(), g);
        std::shuffle(v2.begin(), v2.end(), g);
    }
    
    print(v1, "<  ");
    print(v2, '\n');
}

Возможный вывод:

a b c d >= a b c d 
d a b c >= c b d a 
b d a c >= a d c b 
a c d b <  c d a b

Сообщения о дефектах

Следующие дефектные отчёты, изменяющие поведение, были применены ретроспективно к ранее опубликованным стандартам C++.

DR Применён к Поведение в опубликованном виде Корректное поведение
LWG 142 C++98 допускалось не более min(N1,N2) сравнений, но
это невозможно (эквивалентность определяется двумя сравнениями)
удвоил предел
LWG 1205 C++98 результаты лексикографических сравнений, включающих пустые диапазоны, были неясны прояснено

Смотри также

определяет, являются ли два набора элементов одинаковыми
(шаблон функции & объект-функция алгоритма)
сравнивает два диапазона с помощью трёхстороннего сравнения
(шаблон функции)
сравнивает два диапазона лексикографически
(объект-функция алгоритма)