Namespaces
Variants

std:: lower_bound

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
lower_bound
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Определено в заголовке <algorithm>
(1)
template < class ForwardIt, class T >

ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value ) ;
(constexpr начиная с C++20)
(до C++26)
template < class ForwardIt, class T = typename std:: iterator_traits

< ForwardIt > :: value_type >
constexpr ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value ) ;
(начиная с C++26)
(2)
template < class ForwardIt, class T, class Compare >

ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value, Compare comp ) ;
(constexpr начиная с C++20)
(до C++26)
template < class ForwardIt, class T = typename std:: iterator_traits

< ForwardIt > :: value_type ,
class Compare >
constexpr ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value, Compare comp ) ;
(начиная с C++26)

Выполняет поиск первого элемента в разделённом диапазоне [ first , last ) который не упорядочен перед value .

1) Порядок определяется operator < :

Возвращает первый итератор iter в [ first , last ) для которого bool ( * iter < value ) равно false , или last если такого iter не существует.

Если элементы elem в [ first , last ) не являются разделёнными относительно выражения bool ( elem < value ) , поведение не определено.

(до C++20)

Эквивалентно std :: lower_bound ( first, last, value, std:: less { } ) .

(начиная с C++20)
2) Порядок определяется с помощью comp :
Возвращает первый итератор iter в [ first , last ) для которого bool ( comp ( * iter, value ) ) равен false , или last если такой iter не существует.
Если элементы elem в диапазоне [ first , last ) не являются разделёнными относительно выражения bool ( comp ( elem, value ) ) , поведение не определено.

Содержание

Параметры

first, last - пара итераторов, определяющая разделённый диапазон элементов для проверки
value - значение для сравнения с элементами
comp - бинарный предикат, который возвращает ​ true если первый аргумент упорядочен перед вторым.

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

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

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

Требования к типам
-
ForwardIt должен удовлетворять требованиям LegacyForwardIterator .
-
Compare должен удовлетворять требованиям BinaryPredicate . Не требуется удовлетворять Compare .

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

Итератор на первый элемент диапазона [ first , last ) не упорядоченный перед value , или last если такой элемент не найден.

Сложность

Дано N как std:: distance ( first, last ) :

1) Не более log 2 (N)+O(1) сравнений с value с использованием operator < (until C++20) std:: less { } (since C++20) .
2) Не более log 2 (N)+O(1) применений компаратора comp .

Однако, если ForwardIt не является LegacyRandomAccessIterator , количество инкрементов итератора линейно зависит от N . В частности, итераторы std::map , std::multimap , std::set и std::multiset не являются итераторами произвольного доступа, поэтому следует отдавать предпочтение их функциям-членам lower_bound .

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

Смотрите также реализации в libstdc++ и libc++ .

lower_bound (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value)
{
    return std::lower_bound(first, last, value, std::less{});
}
lower_bound (2)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type,
         class Compare>
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value, Compare comp)
{
    ForwardIt it;
    typename std::iterator_traits<ForwardIt>::difference_type count, step;
    count = std::distance(first, last);
    while (count > 0)
    {
        it = first;
        step = count / 2;
        std::advance(it, step);
        if (comp(*it, value))
        {
            first = ++it;
            count -= step + 1;
        }
        else
            count = step;
    }
    return first;
}
**Примечание:** Весь код C++ внутри тегов `
` и `` оставлен без изменений, как и требовалось. HTML-теги и атрибуты также сохранены в оригинальном виде. Переведены только текстовые элементы вне кодовых блоков.

Примечания

Хотя std::lower_bound требует только, чтобы диапазон [ first , last ) был разделён, этот алгоритм обычно используется в случае, когда [ first , last ) отсортирован, чтобы бинарный поиск был корректным для любого value .

В отличие от std::binary_search , std::lower_bound не требует, чтобы operator < или comp были асимметричными (т.е., a < b и b < a всегда имели разные результаты). Фактически, это даже не требует, чтобы value < * iter или comp ( value, * iter ) были корректно определены для любого итератора iter в диапазоне [ first , last ) .

Макрос тестирования возможностей Значение Стандарт Возможность
__cpp_lib_algorithm_default_value_type 202403 (C++26) Списковая инициализация для алгоритмов ( 1,2 )

Пример

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <vector>
struct PriceInfo { double price; };
int main()
{
    const std::vector<int> data{1, 2, 4, 5, 5, 6};
    for (int i = 0; i < 8; ++i)
    {
        // Поиск первого элемента x, для которого i ≤ x
        auto lower = std::lower_bound(data.begin(), data.end(), i);
        std::cout << i << " ≤ ";
        lower != data.end()
            ? std::cout << *lower << " по индексу " << std::distance(data.begin(), lower)
            : std::cout << "не найдено";
        std::cout << '\n';
    }
    std::vector<PriceInfo> prices{{100.0}, {101.5}, {102.5}, {102.5}, {107.3}};
    for (const double to_find : {102.5, 110.2})
    {
        auto prc_info = std::lower_bound(prices.begin(), prices.end(), to_find,
            [](const PriceInfo& info, double value)
            {
                return info.price < value;
            });
        prc_info != prices.end()
            ? std::cout << prc_info->price << " по индексу " << prc_info - prices.begin()
            : std::cout << to_find << " не найдено";
        std::cout << '\n';
    }
    using CD = std::complex<double>;
    std::vector<CD> nums{{1, 0}, {2, 2}, {2, 1}, {3, 0}};
    auto cmpz = [](CD x, CD y) { return x.real() < y.real(); };
    #ifdef __cpp_lib_algorithm_default_value_type
        auto it = std::lower_bound(nums.cbegin(), nums.cend(), {2, 0}, cmpz);
    #else
        auto it = std::lower_bound(nums.cbegin(), nums.cend(), CD{2, 0}, cmpz);
    #endif
    assert((*it == CD{2, 2}));
}

Вывод:

0 ≤ 1 по индексу 0
1 ≤ 1 по индексу 0
2 ≤ 2 по индексу 1
3 ≤ 4 по индексу 2
4 ≤ 4 по индексу 2
5 ≤ 5 по индексу 3
6 ≤ 6 по индексу 5
7 ≤ не найдено
102.5 по индексу 2
110.2 не найдено

Отчеты о дефектах

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

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 270 C++98 Compare требовалось удовлетворять Compare и T требовалось
быть LessThanComparable (требовался строгий слабый порядок)
требуется только разделение;
разрешены гетерогенные сравнения
LWG 384 C++98 допускалось не более log(N)+1 сравнений исправлено на log 2 (N)+1
LWG 2150 C++98 если существует любой итератор iter в [ first , last ) такой, что
bool ( comp ( * iter, value ) ) равен false , std::lower_bound
мог возвращать любой итератор в [ iter , last )
не может возвращаться итератор после
iter

Смотрите также

возвращает диапазон элементов, соответствующих определённому ключу
(шаблон функции)
разделяет диапазон элементов на две группы
(шаблон функции)
находит точку разделения разделённого диапазона
(шаблон функции)
возвращает итератор на первый элемент больший чем определённое значение
(шаблон функции)
возвращает итератор на первый элемент не меньший чем заданный ключ
(публичная функция-член std::set<Key,Compare,Allocator> )
возвращает итератор на первый элемент не меньший чем заданный ключ
(публичная функция-член std::multiset<Key,Compare,Allocator> )
возвращает итератор на первый элемент не меньший чем заданное значение
(объект функции алгоритма)