Daily bit(e) C++. std::lower_bound, std::upper_bound

Добавлено 24 сентября 2026 в 11:51

Daily bit(e) C++ 123, два алгоритма бинарного поиска – std::lower_bound и std::upper_bound.

Daily bit(e) C++

std::lower_bound и std::upper_bound – пожалуй, два самых практически полезных алгоритма стандартной библиотеки.

Оба алгоритма реализуют бинарный поиск и работают за время O(log n) на отсортированных диапазонах.

std::lower_bound возвращает итератор на первый элемент, который не предшествует заданному значению (то есть первый элемент, который не меньше заданного), а std::upper_bound – на первый элемент, следующий после заданного значения (первый элемент, который строго больше заданного).

Обратите внимание: количество сравнений остается равным O(log n) даже для диапазонов, не поддерживающих произвольный доступ. Однако количество операций инкремента итератора составляет O(n).

#include <algorithm>
#include <vector>

std::vector<int> data{1,2,3,4,5,5,5,6,7,8,9};

// Первый элемент, для которого элемент < значение == false
auto lb = std::lower_bound(data.begin(), data.end(), 5);
// *lb == 5

// то же самое:
lb = std::partition_point(data.begin(), data.end(), [](int el) {
    return el < 5;
});
// *lb == 5

// Первый элемент, для которого значение < элемент == true
auto ub = std::ranges::upper_bound(data, 5); // версия для диапазонов
// *ub == 6

// то же самое:
ub = std::ranges::partition_point(data, [](int el) {
    return not (5 < el);
});
// *ub == 6

// [begin, lb) формирует поддиапазон из элементов меньше
// заданного значения
auto lower = std::ranges::subrange(data.begin(), lb);
// lower == {1, 2, 3, 4}

// [lb, ub) формирует поддиапазон из элементов, равных
// заданному значению
auto equal = std::ranges::subrange(lb, ub);
// equal == {5, 5, 5}

// [ub, end) формирует поддиапазон из элементов больше
// заданного значения
auto high = std::ranges::subrange(ub, data.end());
// high == {6, 7, 8, 9}


std::vector<std::string> strs{"a","ab","fge","cdefgh"};

// Найти первую строку длиной не менее 2 символов
auto el = std::ranges::lower_bound(strs, 2,
    std::less<>{},              // пользовательский компаратор
    [](const std::string& el) { // проекция
        return el.length();
    });
// *el == "ab"

Пример на Compiler Explorer

Теги

C++ / CppDaily bit(e) C++Программирование