Namespaces
Variants

std::ranges:: 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)
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
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
Definido en el encabezado <algorithm>
Firma de llamada
(1)
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 lower_bound ( I first, S last, const T & value,

Comp comp = { } , Proj proj = { } ) ;
(desde C++20)
(hasta 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 lower_bound ( I first, S last, const T & value,

Comp comp = { } , Proj proj = { } ) ;
(desde C++26)
(2)
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 >

lower_bound ( R && r, const T & value, Comp comp = { } , Proj proj = { } ) ;
(desde C++20)
(hasta 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 >

lower_bound ( R && r, const T & value, Comp comp = { } , Proj proj = { } ) ;
(desde C++26)
1) Devuelve un iterador que apunta al primer elemento en el rango [ first , last ) que sea no menor que (es decir, mayor o igual a) value , o last si no se encuentra dicho elemento. El rango [ first , last ) debe estar particionado con respecto a la expresión std:: invoke ( comp, std:: invoke ( proj, element ) , value ) , es decir, todos los elementos para los cuales la expresión es true deben preceder a todos los elementos para los cuales la expresión es false . Un rango completamente ordenado cumple este criterio.
2) Igual que (1) , pero utiliza r como el rango fuente, como si se usara ranges:: begin ( r ) como first y ranges:: end ( r ) como last .

Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:

Contenidos

Parámetros

first, last - el par iterador-centinela que define el rango parcialmente ordenado de elementos a examinar
r - el rango parcialmente ordenado a examinar
value - valor contra el cual comparar los elementos proyectados
comp - predicado de comparación a aplicar a los elementos proyectados
proj - proyección a aplicar a los elementos

Valor de retorno

Iterador que apunta al primer elemento que no es menor que value , o last si no se encuentra dicho elemento.

Complejidad

El número de comparaciones y aplicaciones de la proyección realizadas es logarítmico en la distancia entre first y last (como máximo log 2 (last - first) + O(1) comparaciones y aplicaciones de la proyección). Sin embargo, para un iterador que no modela random_access_iterator , el número de incrementos del iterador es lineal.

Notas

En un rango que está completamente ordenado (o más generalmente, parcialmente ordenado con respecto a value ) después de la proyección, std::ranges::lower_bound implementa el algoritmo de búsqueda binaria. Por lo tanto, std::ranges::binary_search puede implementarse en términos de este.

Macro de prueba de características Valor Std Característica
__cpp_lib_algorithm_default_value_type 202403 (C++26) Inicialización por lista para algoritmos ( 1,2 )

Implementación posible

struct lower_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 = std::ranges::distance(first, last);
        while (count > 0)
        {
            it = first;
            step = count / 2;
            ranges::advance(it, step, last);
            if (comp(std::invoke(proj, *it), value))
            {
                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 lower_bound_fn lower_bound;

Ejemplo

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <iterator>
#include <vector>
namespace ranges = std::ranges;
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 binary_find(I first, S last, const T& value, Comp comp = {}, Proj proj = {})
{
    first = ranges::lower_bound(first, last, value, comp, proj);
    return first != last && !comp(value, proj(*first)) ? first : last;
}
int main()
{
    std::vector data{1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5};
    //                                 ^^^^^^^^^^
    auto lower = ranges::lower_bound(data, 4);
    auto upper = ranges::upper_bound(data, 4);
    std::cout << "found a range [" << ranges::distance(data.cbegin(), lower)
              << ", " << ranges::distance(data.cbegin(), upper) << ") = { ";
    ranges::copy(lower, upper, std::ostream_iterator<int>(std::cout, " "));
    std::cout << "}\n";
    // búsqueda binaria clásica, devolviendo un valor solo si está presente
    data = {1, 2, 4, 8, 16};
    //               ^
    auto it = binary_find(data.cbegin(), data.cend(), 8); // '5' devolvería end()
    if (it != data.cend())
        std::cout << *it << " encontrado en el índice " << ranges::distance(data.cbegin(), it);
    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 it2 = ranges::lower_bound(nums, {2, 0}, cmpz);
    #else
        auto it2 = ranges::lower_bound(nums, CD{2, 0}, cmpz);
    #endif
    assert((*it2 == CD{2, 2}));
}

Salida:

found a range [6, 10) = { 4 4 4 4 }
8 found at index 3

Véase también

devuelve el rango de elementos que coinciden con una clave específica
(objeto función de algoritmo)
divide un rango de elementos en dos grupos
(objeto función de algoritmo)
localiza el punto de partición de un rango particionado
(objeto función de algoritmo)
devuelve un iterador al primer elemento mayor que cierto valor
(objeto función de algoritmo)
devuelve un iterador al primer elemento no menor que el valor dado
(plantilla de función)