std::binary_search
Определён в заголовочном файле <algorithm> | ||
|---|---|---|
template< class ForwardIt, class T >
bool binary_search( ForwardIt first, ForwardIt last,
const T& value );
| (1) |
(до C++26) (constexpr с 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 );
| (начиная с C++26) | |
template< class ForwardIt, class T, class Compare >
bool binary_search( ForwardIt first, ForwardIt last,
const T& value, Compare comp );
| (2) |
(до C++26) (constexpr с 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 );
| (начиная с C++26) |
Проверяет, встречается ли элемент, эквивалентный value, в разбитом на части диапазоне [first, last).
| Если Если выполняется любое из следующих условий, поведение не определено:
| (до C++20) |
| Эквивалентно | (начиная с C++20) |
comp:!bool(comp(*iter, value)) && !bool(comp(value, *iter)) имеет значение true для некоторого итератора iter в [first, last), возвращает true. В противном случае возвращает false.- Для любого элемента
elemиз[first,last)изbool(comp(elem, value))не следует!bool(comp(value, elem)). - Элементы
elemиз[first,last)не разбиты на части относительно выраженийbool(comp(elem, value))и!bool(comp(value, elem)).
Параметры
| first, last | - | пара итераторов, задающая разбитый на части диапазон элементов для проверки |
| value | - | значение, с которым сравниваются элементы |
| comp | - | бинарный предикат, который возвращает true, если первый аргумент упорядочен перед вторым. Сигнатура функции-предиката должна быть эквивалентна следующей: boolpred(constType1&a,constType2&b); Хотя сигнатура не обязана содержать |
| Требования к типам | ||
-ForwardIt должен соответствовать требованиям LegacyForwardIterator. |
||
-Compare должен соответствовать требованиям BinaryPredicate. Соответствие требованиям Compare не требуется. |
||
Возвращаемое значение
true, если найден элемент, эквивалентный value, и false в противном случае.
Сложность
Пусть \(\scriptsize N\)N — это std::distance(first, last):
value, используя operator<(до C++20)std::less{}(начиная с C++20).comp.Однако, если ForwardIt не является LegacyRandomAccessIterator, количество приращений итератора линейно относительно \(\scriptsize N\)N.
Примечания
Хотя std::binary_search требует только, чтобы [first, last) был разбит на части, обычно этот алгоритм используется в тех случаях, когда [first, last) отсортирован, поэтому двоичный поиск корректен для любого value.
std::binary_search лишь проверяет, существует ли эквивалентный элемент. Чтобы получить итератор на этот элемент (если он существует), следует использовать std::lower_bound.
| Макрос проверки функциональности | Значение | Стандарт | Функция |
|---|---|---|---|
__cpp_lib_algorithm_default_value_type | 202403 | (C++26) | Инициализация списком для алгоритмов (1,2) |
Возможная реализация
См. также реализации в libstdc++ и 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)));
}
|
Пример
#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
}
Вывод:
Searching for 1 Found 1 Searching for 2 Not found! Searching for 3 Found 3
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| LWG 270 | C++98 |
Compare должен был соответствовать требованиям Compare, а T должен былбыть LessThanComparable (требовался строгий слабый порядок) | требуется только разбиение на части; разрешены гетерогенные сравнения |
| LWG 787 | C++98 | допускалось не более \(\scriptsize \log_{2}(N)+2\)log2(N)+2 сравнений | исправлено на \(\scriptsize \log_{2}(N)+O(1)\)log2(N)+O(1) |
См. также
| находит диапазон элементов, соответствующих заданному значению, с помощью двоичного поиска (шаблон функции и объект-функция алгоритма) |
|
|
(C++20) | |
| находит с помощью двоичного поиска первый элемент, не меньший заданного значения (шаблон функции и объект-функция алгоритма) |
|
|
(C++20) | |
| находит с помощью двоичного поиска первый элемент, больший заданного значения (шаблон функции и объект-функция алгоритма) |
|
|
(C++20) | |
|
(C++20) | определяет с помощью двоичного поиска, существует ли элемент в диапазоне (объект-функция алгоритма) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/binary_search