Namespaces
Variants

std::ranges::binary_search

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, 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)

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

Operaciones de ordenación
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


 
Algoritmos restringidos
Todos los nombres en este menú pertenecen al espacio de nombres std::ranges
Operaciones de secuencia no modificadoras
Operaciones de secuencia modificadoras
Operaciones de partición
Operaciones de ordenación
Operaciones de búsqueda binaria (en rangos ordenados)
       
       
Operaciones de conjunto (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de plegado
Operaciones sobre almacenamiento no inicializado
Tipos de retorno
 
Definido en el encabezado <algorithm>
Firma de llamada
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 = {} );
(1) (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)
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 = {} );
(2) (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 [first, last).
2) Igual que (1), pero usa r como rango fuente, como si se usara ranges::begin(r) como first y ranges::end(r) como last.

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

  • particionado con respecto a std::invoke(comp, std::invoke(proj, element), value) (es decir, todos los elementos proyectados para los cuales la expresión es true preceden a todos los elementos para los cuales 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 estos criterios.

Las entidades similares a funciones descritas en esta página son objetos función de algoritmo (informalmente conocidos como niebloids), es decir:

Parámetros

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

Valor de retorno

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

Complejidad

El número de comparaciones y proyecciones realizadas es logarítmico en la distancia entre first y last (como máximo log2(last - first) + O(1) comparaciones y proyecciones). Sin embargo, para pares iterador-centinela que no modelan std::random_access_iterator, el número de incrementos de 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 usar std::ranges::lower_bound en su lugar.

Macro de prueba de características Valor Std Característica
__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 haystack = {1, 3, 4, 5, 9};
    static_assert(std::ranges::is_sorted(haystack));
    
    for (const int needle : std::views::iota(1)
                          | std::views::take(3))
    {
        std::cout << "Searching for " << needle << ": ";
        std::ranges::binary_search(haystack, needle)
            ? std::cout << "found " << needle << '\n'
            : std::cout << "no dice!\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:

Searching for 1: found 1
Searching for 2: no dice!
Searching for 3: found 3

Véase también

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