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
Definido en el encabezado <algorithm>
(1)
template < class ForwardIt, class T >

ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value ) ;
(constexpr desde C++20)
(hasta 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 ) ;
(desde C++26)
(2)
template < class ForwardIt, class T, class Compare >

ForwardIt lower_bound ( ForwardIt first, ForwardIt last,

const T & value, Compare comp ) ;
(constexpr desde C++20)
(hasta 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 ) ;
(desde C++26)

Busca el primer elemento en el rango particionado [ first , last ) que no esté ordenado antes de value .

1) El orden está determinado por operator < :

Retorna el primer iterador iter en [ first , last ) donde bool ( * iter < value ) es false , o last si no existe tal iter .

Si los elementos elem de [ first , last ) no están particionados con respecto a la expresión bool ( elem < value ) , el comportamiento es indefinido.

(until C++20)

Equivalente a std :: lower_bound ( first, last, value, std:: less { } ) .

(since C++20)
2) El orden está determinado por comp :
Devuelve el primer iterador iter en [ first , last ) donde bool ( comp ( * iter, value ) ) es false , o last si no existe tal iter .
Si los elementos elem de [ first , last ) no están particionados con respecto a la expresión bool ( comp ( elem, value ) ) , el comportamiento es indefinido.

Contenidos

Parámetros

first, last - el par de iteradores que define el rango particionado de elementos a examinar
value - valor contra el cual se comparan los elementos
comp - predicado binario que retorna ​ true si el primer argumento está ordenado antes del segundo.

La firma de la función predicado debe ser equivalente a lo siguiente:

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

Aunque la firma no necesita tener const & , la función no debe modificar los objetos pasados a ella y debe poder aceptar todos los valores de tipo (posiblemente const) Type1 y Type2 independientemente de la categoría de valor (por lo tanto, Type1 & no está permitido , ni tampoco Type1 a menos que para Type1 un movimiento sea equivalente a una copia (since C++11) ).
El tipo Type1 debe ser tal que un objeto de tipo ForwardIt pueda ser desreferenciado y luego convertido implícitamente a Type1 . El tipo Type2 debe ser tal que un objeto de tipo T pueda ser convertido implícitamente a Type2 . ​

Requisitos de tipo
-
ForwardIt debe cumplir con los requisitos de LegacyForwardIterator .
-
Compare debe cumplir con los requisitos de BinaryPredicate . No se requiere que satisfaga Compare .

Valor de retorno

Iterador al primer elemento del rango [ first , last ) no ordenado antes de value , o last si no se encuentra tal elemento.

Complejidad

Dado N como std:: distance ( first, last ) :

1) Como máximo log 2 (N)+O(1) comparaciones con value usando operator < (hasta C++20) std:: less { } (desde C++20) .
2) Como máximo log 2 (N)+O(1) aplicaciones del comparador comp .

Sin embargo, si ForwardIt no es un LegacyRandomAccessIterator , el número de incrementos del iterador es lineal en N . Cabe destacar que los iteradores de std::map , std::multimap , std::set , y std::multiset no son de acceso aleatorio, por lo que deberían preferirse sus funciones miembro lower_bound .

Implementación posible

Consulte también las implementaciones en libstdc++ y 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;
}

Notas

Aunque std::lower_bound solo requiere que [ first , last ) esté particionado, este algoritmo se utiliza normalmente en el caso donde [ first , last ) está ordenado, de modo que la búsqueda binaria es válida para cualquier value .

A diferencia de std::binary_search , std::lower_bound no requiere que operator < o comp sean asimétricos (es decir, a < b y b < a siempre tengan resultados diferentes). De hecho, ni siquiera requiere que value < * iter o comp ( value, * iter ) estén bien formados para cualquier iterador iter en [ first , last ) .

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

Ejemplo

#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)
    {
        // Buscar el primer elemento x tal que i ≤ x
        auto lower = std::lower_bound(data.begin(), data.end(), i);
        std::cout << i << " ≤ ";
        lower != data.end()
            ? std::cout << *lower << " en el índice " << std::distance(data.begin(), lower)
            : std::cout << "no encontrado";
        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 << " en el índice " << prc_info - prices.begin()
            : std::cout << to_find << " no encontrado";
        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}));
}

Salida:

0 ≤ 1 en el índice 0
1 ≤ 1 en el índice 0
2 ≤ 2 en el índice 1
3 ≤ 4 en el índice 2
4 ≤ 4 en el índice 2
5 ≤ 5 en el índice 3
6 ≤ 6 en el índice 5
7 ≤ no encontrado
102.5 en el índice 2
110.2 no encontrado

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 270 C++98 Compare se requería que cumpliera con Compare y T se requería
que fuera LessThanComparable (se requería ordenamiento débil estricto)
solo se requiere una partición;
se permiten comparaciones heterogéneas
LWG 384 C++98 se permitían como máximo log(N)+1 comparaciones se corrigió a log 2 (N)+1
LWG 2150 C++98 si existe cualquier iterador iter en [ first , last ) tal que
bool ( comp ( * iter, value ) ) es false , std::lower_bound
podría retornar cualquier iterador en [ iter , last )
no se puede retornar ningún iterador después de
iter

Véase también

devuelve el rango de elementos que coinciden con una clave específica
(plantilla de función)
divide un rango de elementos en dos grupos
(plantilla de función)
localiza el punto de partición de un rango particionado
(plantilla de función)
devuelve un iterador al primer elemento mayor que cierto valor
(plantilla de función)
devuelve un iterador al primer elemento no menor que la clave dada
(función miembro pública de std::set<Key,Compare,Allocator> )
devuelve un iterador al primer elemento no menor que la clave dada
(función miembro pública de std::multiset<Key,Compare,Allocator> )
devuelve un iterador al primer elemento no menor que el valor dado
(objeto función de algoritmo)