Namespaces
Variants

std::ranges::upper_bound

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









 
Ограниченные алгоритмы
Все имена в этом меню принадлежат пространству имен std::ranges
Немодифицирующие операции над последовательностями
Модифицирующие операции над последовательностями
Операции разделения
Операции сортировки
Операции бинарного поиска (на отсортированных диапазонах)
       
       
Операции над множествами (на отсортированных диапазонах)
Операции с кучей
Операции минимума/максимума
       
       
Операции перестановок
Операции свертки
Операции над неинициализированной памятью
Возвращаемые типы
 
Определен в заголовке <algorithm>
Сигнатура вызова
template< std::forward_iterator I, std::sentinel_for<I> S,
          class T, class Proj = std::identity,
          std::indirect_strict_weak_order
              <const T*, std::projected<I, Proj>> Comp = ranges::less >
constexpr I upper_bound( I first, S last, const T& value,
                         Comp comp = {}, Proj proj = {} );
(1) (начиная с C++20)
(до C++26)
template< std::forward_iterator I, std::sentinel_for<I> S,
          class Proj = std::identity,
          class T = std::projected_value_t<I, Proj>,
          std::indirect_strict_weak_order
              <const T*, std::projected<I, Proj>> Comp = ranges::less >
constexpr I upper_bound( I first, S last, const T& value,
                         Comp comp = {}, Proj proj = {} );
(начиная с C++26)
template< ranges::forward_range R,
          class T, class Proj = std::identity,
          std::indirect_strict_weak_order
              <const T*, std::projected<ranges::iterator_t<R>,
                                        Proj>> Comp = ranges::less >
constexpr ranges::borrowed_iterator_t<R>
    upper_bound( R&& r, const T& value, Comp comp = {}, Proj proj = {} );
(2) (начиная с C++20)
(до C++26)
template< ranges::forward_range R,
          class Proj = std::identity,
          class T = std::projected_value_t<ranges::iterator_t<R>, Proj>,
          std::indirect_strict_weak_order
              <const T*, std::projected<ranges::iterator_t<R>,
                                        Proj>> Comp = ranges::less >
constexpr ranges::borrowed_iterator_t<R>
    upper_bound( R&& r, const T& value, Comp comp = {}, Proj proj = {} );
(начиная с C++26)
1) Возвращает итератор, указывающий на первый элемент в диапазоне [first, last) который больше чем value, или last если такой элемент не найден. Диапазон [first, last) должен быть разделен относительно выражения или !comp(value, element), т.е. все элементы, для которых выражение true должно предшествовать всем элементам, для которых выражение false. Полностью отсортированный диапазон удовлетворяет этому критерию.
2) Аналогично (1), но использует r в качестве исходного диапазона, как если бы ranges::begin(r) использовалось как first и ranges::end(r) как last.

Описанные на этой странице функциональные объекты являются объектами функций алгоритмов (неофициально известными как niebloids), а именно:

Параметры

first, last - пара итератор-страж, определяющая частично упорядоченный диапазон элементов для проверки
r - частично упорядоченный диапазон для проверки
value - значение для сравнения с элементами
pred - предикат для применения к проецируемым элементам
proj - проекция для применения к элементам

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

Итератор, указывающий на первый элемент, который больше чем value , или last если такой элемент не найден.

Сложность

Количество сравнений и применений проекции, выполняемых алгоритмом, логарифмически зависит от расстояния между first и last (не более log 2 (last - first) + O(1) сравнений и применений проекции). Однако для итераторов, не моделирующих random_access_iterator , количество инкрементов итераторов является линейным.

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

struct upper_bound_fn
{
    template<std::forward_iterator I, std::sentinel_for<I> S,
             class Proj = std::identity, class T = std::projected_value_t<I, Proj>,
             std::indirect_strict_weak_order
                 <const T*, std::projected<I, Proj>> Comp = ranges::less>
    constexpr I operator()(I first, S last, const T& value,
                           Comp comp = {}, Proj proj = {}) const
    {
        I it;
        std::iter_difference_t<I> count, step;
        count = ranges::distance(first, last);
        while (count > 0)
        {
            it = first; 
            step = count / 2;
            ranges::advance(it, step, last);
            if (!comp(value, std::invoke(proj, *it)))
            {
                first = ++it;
                count -= step + 1;
            }
            else
                count = step;
        }
        return first;
    }
    template<ranges::forward_range R, class Proj = std::identity,
             class T = std::projected_value_t<ranges::iterator_t<R>, Proj>,
             std::indirect_strict_weak_order
                 <const T*, std::projected<ranges::iterator_t<R>,
                                           Proj>> Comp = ranges::less>
    constexpr ranges::borrowed_iterator_t<R>
        operator()(R&& r, const T& value, Comp comp = {}, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), value,
                       std::ref(comp), std::ref(proj));
    }
};
inline constexpr upper_bound_fn upper_bound;

Примечания

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

Пример

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
    namespace ranges = std::ranges;
    std::vector<int> data{1, 1, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6};
    {
        auto lower = ranges::lower_bound(data.begin(), data.end(), 4);
        auto upper = ranges::upper_bound(data.begin(), data.end(), 4);
        ranges::copy(lower, upper, std::ostream_iterator<int>(std::cout, " "));
        std::cout << '\n';
    }
    {
        auto lower = ranges::lower_bound(data, 3);
        auto upper = ranges::upper_bound(data, 3);
        ranges::copy(lower, upper, std::ostream_iterator<int>(std::cout, " "));
        std::cout << '\n';
    }
    using CD = std::complex<double>;
    std::vector<CD> nums{{1, 0}, {2, 2}, {2, 1}, {3, 0}, {3, 1}};
    auto cmpz = [](CD x, CD y) { return x.real() < y.real(); };
    #ifdef __cpp_lib_algorithm_default_value_type
        auto it = ranges::upper_bound(nums, {2, 0}, cmpz);
    #else
        auto it = ranges::upper_bound(nums, CD{2, 0}, cmpz);
    #endif
    assert((*it == CD{3, 0}));
}

Вывод:

4 4 4 
3 3 3 3

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

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