std::ranges:: binary_search
|
Definido en el encabezado
<algorithm>
|
||
|
Firma de llamada
|
||
| (1) | ||
|
template
<
std::
forward_iterator
I,
std::
sentinel_for
<
I
>
S,
class
T,
class
Proj
=
std::
identity
,
|
(desde C++20)
(hasta C++26) |
|
|
template
<
std::
forward_iterator
I,
std::
sentinel_for
<
I
>
S,
class
Proj
=
std::
identity
,
|
(desde C++26) | |
| (2) | ||
|
template
<
ranges::
forward_range
R,
class
T,
class
Proj
=
std::
identity
,
|
(desde C++20)
(hasta C++26) |
|
|
template
<
ranges::
forward_range
R,
class
Proj
=
std::
identity
,
|
(desde C++26) | |
[
first
,
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 siguientes requisitos:
- 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 algorithm function objects (conocidas informalmente como niebloids ), es decir:
- No se pueden especificar listas de argumentos de plantilla explícitas al llamar a cualquiera de ellos.
- Ninguno de ellos es visible para la búsqueda dependiente de argumento .
- Cuando cualquiera de ellos es encontrado mediante la búsqueda no calificada normal como el nombre a la izquierda del operador de llamada a función, la búsqueda dependiente de argumento queda inhibida.
Contenidos |
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 contra el cual 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 log 2 (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 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,
std::ranges::lower_bound
debe utilizarse 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 de lista para algoritmos ( 1,2 ) |
Implementación posible
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 << "Buscando " << needle << ": "; std::ranges::binary_search(haystack, needle) ? std::cout << "encontrado " << needle << '\n' : std::cout << "¡sin suerte!\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: encontrado 1 Buscando 2: ¡sin suerte! Buscando 3: encontrado 3
Véase también
|
(C++20)
|
devuelve el rango de elementos que coinciden con una clave específica
(objeto función de algoritmo) |
|
(C++20)
|
devuelve un iterador al primer elemento
no menor
que el valor dado
(objeto función de algoritmo) |
|
(C++20)
|
devuelve un iterador al primer elemento
mayor
que cierto valor
(objeto función de algoritmo) |
|
(C++23)
(C++23)
|
verifica si el rango contiene el elemento o subrango dado
(objeto función de algoritmo) |
|
determina si un elemento existe en un rango parcialmente ordenado
(plantilla de función) |