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) 内。
operator< 检查:
|
如果 如果以下任一条件满足,则行为未定义:
|
(直到 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
。
谓词函数的签名应等价于如下形式: bool pred ( const Type1 & a, const Type2 & b ) ;
虽然签名不必包含
const
&
,但函数不得修改传递的对象,且必须能接受所有(可能为 const 的)
|
| 类型要求 | ||
-
ForwardIt
必须满足
LegacyForwardIterator
的要求。
|
||
-
Compare
必须满足
BinaryPredicate
的要求,但不必满足
Compare
的要求。
|
||
返回值
当找到与 value 等价的元素时返回 true ,否则返回 false 。
复杂度
给定 N 为 std:: distance ( first, last ) :
然而,若
ForwardIt
不满足
LegacyRandomAccessIterator
要求,则迭代器递增次数与
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 ) |
可能的实现
| 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 << "正在搜索 " << needle << '\n'; if (std::binary_search(haystack.begin(), haystack.end(), needle)) std::cout << "已找到 " << needle << '\n'; else std::cout << "未找到!\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 }
输出:
正在搜索 1 已找到 1 正在搜索 2 未找到! 正在搜索 3 已找到 3
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| 缺陷报告 | 应用于 | 发布时行为 | 正确行为 |
|---|---|---|---|
| LWG 270 | C++98 |
Compare
需要满足
Compare
且
T
需要
是 LessThanComparable (要求严格弱序) |
仅需满足划分要求;
允许异构比较 |
| LWG 787 | C++98 | 最多允许 log 2 (N)+2 次比较 | 修正为 log 2 (N)+O(1) |
另见
| 使用二分查找查找与给定值匹配的元素范围 (函数模板 & 算法函数对象) | |
(C++20) |
|
| 使用二分查找查找第一个不小于给定值的元素 (函数模板 & 算法函数对象) | |
(C++20) |
|
| 使用二分查找查找第一个大于给定值的元素 (函数模板 & 算法函数对象) | |
(C++20) |
|
(C++20) |
使用二分查找判断范围内是否存在某元素 (算法函数对象) |