std::binary_search
| 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).
operator<:
|
Si Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:
|
(hasta C++20) |
|
Equivalente a |
(desde C++20) |
comp:!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.- Para cualquier elemento
elemde[first,last),bool(comp(elem, value))no implica!bool(comp(value, elem)). - Los elementos
elemde[first,last)no están particionados con respecto a las expresionesbool(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:
Aunque la firma no necesita tener |
| 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):
value usando operator<(hasta C++20)std::less{}(desde C++20).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 requeridoque 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) | |
(C++20) |
|
| encuentra el primer elemento no menor que el valor dado usando búsqueda binaria (plantilla de función & objeto función de algoritmo) | |
(C++20) |
|
| encuentra el primer elemento mayor que el valor dado usando búsqueda binaria (plantilla de función & objeto función de algoritmo) | |
(C++20) |
|
(C++20) |
determina si existe un elemento en un rango usando búsqueda binaria (objeto función de algoritmo) |