Espacios de nombres
Variantes

std::ranges::binary_search

De cppreference.com
 
 
Biblioteca de algoritmos
Políticas de ejecución (C++17)
Operaciones de secuencia no modificantes
(C++11)(C++11)(C++11)
(C++17)
Operaciones de secuencia modificantes
Operaciones en almacenamiento no inicializado
Operaciones de partición
Operaciones de ordenación
(C++11)
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de pila
(C++11)
Operaciones mínimo/máximo
(C++11)
(C++17)
Permutaciones
Operaciones numéricas
Bibliotecas C
 
Algoritmos restringidos
Operaciones de secuencia no modificantes
Operaciones de secuencia modificantes
Operaciones en almacenamiento sin inicializar
Operaciones de partición
Operaciones de ordenamiento
Operaciones de búsqueda binaria
Operaciones de conjuntos (en rangos ordenados)
Operaciones de montículo/montón
Operaciones de mínimo/máximo
Permutaciones
 
<tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody>
Definido en el archivo de encabezado <algorithm>
Signatura de la 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 bool binary_search( 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 bool binary_search( 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 bool binary_search( 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 bool binary_search( R&& r, const T& value, Comp comp = {}, Proj proj = {} );
(desde C++26)
1) Comprueba si un elemento proyectado equivalente a value aparece dentro del rango [firstlast).
2) Igual que (1), pero usa r como el rango fuente, como si usara ranges::begin(r) como first y ranges::end(r) como last.

Para que ranges::binary_search tenga éxito, el rango [firstlast) debe estar al menos parcialmente ordenado con respecto a value, es decir, debe satisfacer todos los requisitos siguientes:

  • particionado con respecto a std::invoke(comp, std::invoke(proj, element), value) (es decir, todos los elementos proyectados para los que la expresión es true preceden a todos los elementos para los que la expresión es false).
  • particionado con respecto a !std::invoke(comp, value, std::invoke(proj, element)).
  • para todos los elementos, si std::invoke(comp, std::invoke(proj, element), value) es true entonces !std::invoke(comp, value, std::invoke(proj, element)) también es true.

Un rango completamente ordenado cumple con estos criterios.

Las entidades similares a funciones descritas en esta página son niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Parámetros

first, last - El rango de los elementos a examinar.
r - El rango de los elementos a examinar.
value - El valor con el que comparar los elementos.
comp - La función de comparación que se aplicará a los elementos proyectados.
proj - La proyección que se aplicará a los elementos.

Valor de retorno

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

Complejidad

La cantidad de comparaciones y proyecciones realizadas es logarítmica en la distancia entre first y last (como máximo log
2
(last - first) + O(1)
comparaciones y proyecciones). Sin embargo, para el par iterador-centinela que no modela std::random_access_iterator, la cantidad de incrementos del iterador es lineal.

Notas

std::ranges::binary_search no devuelve un iterador al elemento encontrado cuando se encuentra un elemento cuya proyección es igual a value. Si se desea un iterador, se debe utilizar std::ranges::lower_bound en su lugar.


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

Posible implementación

struct binary_search_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 bool operator()(I first, S last, const T& value,
                              Comp comp = {}, Proj proj = {}) const
    {
        auto x = ranges::lower_bound(first, last, value, comp, proj);
        return (!(x == last) && !(std::invoke(comp, value, std::invoke(proj, *x))));
    }
    
    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 bool operator()(R&& r, const T& value, Comp comp = {}, Proj proj = {}) const
    {
        return (*this)(ranges::begin(r), ranges::end(r), value,
                       std::move(comp), std::move(proj));
    }
};

inline constexpr binary_search_fn binary_search;

Ejemplo

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

int main()
{
    constexpr static auto pajar = {1, 3, 4, 5, 9};
    static_assert(std::ranges::is_sorted(pajar));
    
    for (const int aguja : std::views::iota(1)
                          | std::views::take(3))
    {
        std::cout << "Buscando " << aguja << ": ";
        std::ranges::binary_search(pajar, aguja)
            ? std::cout << "Se encontró " << aguja << '\n'
            : std::cout << "¡No se encontró!\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::ranges::binary_search(nums, {4, 2}, cmpz));
    #else
        assert(std::ranges::binary_search(nums, CD{4, 2}, cmpz));
    #endif
}

Salida:

Buscando 1: Se encontró 1
Buscando 2: ¡No se encontró!
Buscando 3: Se encontró 3

Véase también

Devuelve un rango de elementos que coinciden con una clave especifica.
(niebloid) [editar]
Devuelve un iterador al primer elemento no menor que el valor dado.
(niebloid) [editar]
Devuelve un iterador al primer elemento mayor que un cierto valor.
(niebloid) [editar]
Comprueba si el rango contiene el elemento dado o un subrango.
(niebloid) [editar]
Determina si un elemento existe en un rango parcialmente ordenado.
(plantilla de función) [editar]