Namespaces
Variants

std::binary_search

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p.ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Ordenamiento y operaciones relacionadas
Operaciones de partición
(C++11)    

Operaciones de ordenamiento
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjunto (en rangos ordenados)
Operaciones de mezcla (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Definido en el encabezado <algorithm>
template< class ForwardIt, class T >
bool binary_search( ForwardIt first, ForwardIt last,
                    const T& value );
(1) (hasta C++26)
(constexpr desde C++20)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type >
constexpr bool binary_search( ForwardIt first, ForwardIt last,
                              const T& value );
(desde C++26)
template< class ForwardIt, class T, class Compare >
bool binary_search( ForwardIt first, ForwardIt last,
                    const T& value, Compare comp );
(2) (hasta C++26)
(constexpr desde C++20)
template< class ForwardIt, class T = typename std::iterator_traits
                                         <ForwardIt>::value_type,
          class Compare >
constexpr bool binary_search( ForwardIt first, ForwardIt last,
                              const T& value, Compare comp );
(desde C++26)

Comprueba si un elemento equivalente a value aparece dentro del rango particionado [first, last).

1) La equivalencia se comprueba usando operator<:

Si !bool(*iter < value) && !bool(value < *iter) es true para algún iterador iter en [first, last), devuelve true. De lo contrario devuelve false.

Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:

  • Para cualquier elemento elem de [first, last), bool(elem < value) no implica !bool(value < elem).
  • Los elementos elem de [first, last) no están particionados con respecto a las expresiones bool(elem < value) y !bool(value < elem).
(hasta C++20)

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

(desde C++20)
2) La equivalencia se comprueba usando comp:
Si !bool(comp(*iter, value)) && !bool(comp(value, *iter)) es true para algún iterador iter en [first, last), devuelve true. De lo contrario devuelve false.
Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:
  • Para cualquier elemento elem de [first, last), bool(comp(elem, value)) no implica !bool(comp(value, elem)).
  • Los elementos elem de [first, last) no están particionados con respecto a las expresiones bool(comp(elem, value)) y !bool(comp(value, elem)).

Parámetros

first, last - el par de iteradores que definen el rango particionadorango de elementos a examinar
value - valor con el que comparar los elementos
comp - predicado binario que devuelve ​true si el primer argumento está ordenado antes que el segundo.

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

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

Aunque la firma no necesita tener const &, la función no debe modificar los objetos que se le pasan y debe ser capaz de 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 Type1 a menos que para Type1 un movimiento sea equivalente a una copia(desde C++11)).
Los tipos Type1 y Type2 deben ser tales que un objeto de tipo T pueda convertirse implícitamente tanto a Type1 como a Type2, y un objeto de tipo ForwardIt pueda desreferenciarse y luego convertirse implícitamente tanto a Type1 como a Type2. ​

Requisitos de tipo
-
ForwardIt debe cumplir los requisitos de LegacyForwardIterator.
-
Compare debe cumplir los requisitos de BinaryPredicate. No es necesario que satisfaga Compare.

Valor de retorno

true si se encuentra un elemento equivalente a value, false en caso contrario.

Complejidad

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

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

Notas

Aunque std::binary_search solo requiere que [first, last) esté particionado, este algoritmo se suele usar en el caso de que [first, last) esté ordenado, para que la búsqueda binaria sea válida para cualquier value.

std::binary_search solo comprueba si existe un elemento equivalente. Para obtener un iterador a ese elemento (si existe), se debe usar std::lower_bound.

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

Posible implementación

Véanse también las implementaciones en libstdc++ y libc++.

binary_search (1)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type>
bool binary_search(ForwardIt first, ForwardIt last, const T& value)
{
    return std::binary_search(first, last, value, std::less{});
}
binary_search (2)
template<class ForwardIt, class T = typename std::iterator_traits<ForwardIt>::value_type,
         class Compare>
bool binary_search(ForwardIt first, ForwardIt last, const T& value, Compare comp)
{
    first = std::lower_bound(first, last, value, comp);
    return (!(first == last) and !(comp(value, *first)));
}

Ejemplo

#include <algorithm>
#include <cassert>
#include <complex>
#include <iostream>
#include <vector>

int main()
{
    const auto haystack = {1, 3, 4, 5, 9};
    
    for (const auto needle : {1, 2, 3})
    {
        std::cout << "Searching for " << needle << '\n';
        if (std::binary_search(haystack.begin(), haystack.end(), needle))
            std::cout << "Found " << needle << '\n';
        else
            std::cout << "Not found!\n";
    }

    using CD = std::complex<double>;
    std::vector<CD> nums{{1, 1}, {2, 3}, {4, 2}, {4, 3}};
    auto cmpz = [](CD x, CD y){ return abs(x) < abs(y); };
    #ifdef __cpp_lib_algorithm_default_value_type
        assert(std::binary_search(nums.cbegin(), nums.cend(), {4, 2}, cmpz));
    #else
        assert(std::binary_search(nums.cbegin(), nums.cend(), CD{4, 2}, cmpz));
    #endif
}

Salida:

Searching for 1
Found 1
Searching for 2
Not found!
Searching for 3
Found 3

Informes de defectos

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

DR Aplicado a Comportamiento como se publicó Comportamiento correcto
LWG 270 C++98 Compare Se requería que Compare y T era requerido
que LessThanComparable (orden débil estricto requerido)
solo se requiere una partición;
se permiten comparaciones heterogéneas
LWG 787 C++98 se permitían como máximo log2(N)+2 comparaciones corregido a log2(N)+O(1)

Véase también

encuentra el rango de elementos que coinciden con el valor dado usando búsqueda binaria
(plantilla de función & objeto función de algoritmo)
encuentra el primer elemento no menor que el valor dado usando búsqueda binaria
(plantilla de función & objeto función de algoritmo)
encuentra el primer elemento mayor que el valor dado usando búsqueda binaria
(plantilla de función & objeto función de algoritmo)
determina si existe un elemento en un rango usando búsqueda binaria
(objeto función de algoritmo)