Namespaces
Variants

std:: upper_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)
upper_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 upper_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 upper_bound ( ForwardIt first, ForwardIt last,

const T & value ) ;
(desde C++26)
(2)
template < class ForwardIt, class T, class Compare >

ForwardIt upper_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 upper_bound ( ForwardIt first, ForwardIt last,

const T & value, Compare comp ) ;
(desde C++26)

Busca el primer elemento en el rango particionado [ first , last ) que está ordenado después de value .

1) El orden está determinado por operator < :

Retorna el primer iterador iter en [ first , last ) donde bool ( value < * iter ) es true , 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 ( value < elem ) , el comportamiento es indefinido.

(hasta C++20)

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

(desde C++20)
2) El orden está determinado por comp :
Devuelve el primer iterador iter en [ first , last ) donde bool ( comp ( value, * iter ) ) es true , 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 ( value, elem ) ) , 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 comparar 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 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 (desde C++11) ).
El tipo Type1 debe ser tal que un objeto de tipo T pueda convertirse implícitamente a Type1 . El tipo Type2 debe ser tal que un objeto de tipo ForwardIt pueda ser desreferenciado y luego 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 ) ordenado después de value , o last si no se encuentra dicho elemento.

Complejidad

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

1) Como máximo log 2 (N)+O(1) comparaciones con value usando operator < (until C++20) std:: less { } (since 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 upper_bound .

Implementación posible

Consulte también las implementaciones en libstdc++ y libc++ .

upper_bound (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
ForwardIt upper_bound(ForwardIt first, ForwardIt last, const T& value)
{
    return std::upper_bound(first, last, value, std::less{});
}
upper_bound (2)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type,
         class Compare>
ForwardIt upper_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(value, *it))
        {
            first = ++it;
            count -= step + 1;
        } 
        else
            count = step;
    }
    return first;
}

Notas

Aunque std::upper_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 .

Para cualquier iterador iter en [ first , last ) , std::upper_bound requiere que value < * iter y comp ( value, * iter ) estén bien formados, mientras que std::lower_bound requiere que * iter < value y comp ( * iter, value ) estén bien formados en su lugar.

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 < 7; ++i)
    {
        // Buscar el primer elemento que sea mayor que i
        auto upper = std::upper_bound(data.begin(), data.end(), i);
        std::cout << i << " < ";
        upper != data.end()
            ? std::cout << *upper << " en el índice " << std::distance(data.begin(), upper)
            : std::cout << "no encontrado";
        std::cout << '\n';
    }
    std::vector<PriceInfo> prices{{100.0}, {101.5}, {102.5}, {102.5}, {107.3}};
    for (double to_find : {102.5, 110.2})
    {
        auto prc_info = std::upper_bound(prices.begin(), prices.end(), to_find,
            [](double value, const PriceInfo& info)
            {
                return value < info.price;
            });
        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}, {3, 1}};
    auto cmpz = [](CD x, CD y) { return x.real() < y.real(); };
    #ifdef __cpp_lib_algorithm_default_value_type
        auto it = std::upper_bound(nums.cbegin(), nums.cend(), {2, 0}, cmpz);
    #else
        auto it = std::upper_bound(nums.cbegin(), nums.cend(), CD{2, 0}, cmpz);
    #endif
    assert((*it == CD{3, 0}));
}

Salida:

0 < 1 en el índice 0
1 < 2 en el índice 1
2 < 4 en el índice 2
3 < 4 en el índice 2
4 < 5 en el índice 3
5 < 6 en el índice 5
6 < no encontrado 
107.3 en el índice 4
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 debía satisfacer Compare y T debía ser
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 2 (N)+1 comparaciones corregido a log 2 (N)+O(1)
LWG 577 C++98 last no podía ser devuelto permitido
LWG 2150 C++98 si existe cualquier iterador iter en [ first , last ) tal que
bool ( comp ( value, * iter ) ) es true , std::upper_bound
podría devolver cualquier iterador en [ iter , last )
no se puede devolver 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)
devuelve un iterador al primer elemento no menor que el valor dado
(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
(objeto función de algoritmo)
devuelve un iterador al primer elemento mayor que la clave dada
(función miembro pública de std::set<Key,Compare,Allocator> )
devuelve un iterador al primer elemento mayor que la clave dada
(función miembro pública de std::multiset<Key,Compare,Allocator> )