名稱空間
變體
操作

std::binary_search

來自 cppreference.com
< cpp‎ | 演算法
 
 
演算法庫
有約束演算法與針對範圍的演算法 (C++20)
有約束的演算法,例如 ranges::copyranges::sort 等……
執行策略 (C++17)
排序及相關操作
劃分操作
排序操作
二分搜尋操作
(於已劃分範圍上)
binary_search
集合操作(於已排序範圍上)
歸併操作(於已排序範圍上)
堆操作
最小/最大值操作
(C++11)
(C++17)
字典序比較操作
排列操作
C 庫
數值操作
未初始化記憶體上的操作
 
定義於標頭檔案 <algorithm>
(1)
template< class ForwardIt, class T >

bool binary_search( ForwardIt first, ForwardIt last,

                    const T& value );
(C++20 起為 constexpr)
(直到 C++26)
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 起)
(2)
template< class ForwardIt, class T, class Compare >

bool binary_search( ForwardIt first, ForwardIt last,

                    const T& value, Compare comp );
(C++20 起為 constexpr)
(直到 C++26)
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 等價的元素是否出現在已劃分的範圍 [firstlast) 中。

1) 等價性使用 operator< 檢查。

如果在 [firstlast) 中存在某個迭代器 iter,使得 !bool(*iter < value) && !bool(value < *iter)true,則返回 true。否則返回 false

如果滿足以下任何條件,則行為是未定義的:

  • 對於 [firstlast) 的任何元素 elembool(elem < value) 不意味著 !bool(value < elem)
  • 範圍 [firstlast) 的元素 elem 未根據表示式 bool(elem < value)!bool(value < elem) 進行 劃分
(C++20 前)

等價於 std::binary_search(first, last, value, std::less{})

(C++20 起)
2) 等價性使用 comp 檢查。
如果在 [firstlast) 中存在某個迭代器 iter,使得 !bool(comp(*iter, value)) && !bool(comp(value, *iter))true,則返回 true。否則返回 false
如果滿足以下任何條件,則行為未定義:
  • 對於 [firstlast) 的任何元素 elembool(comp(elem, value)) 不意味著 !bool(comp(value, elem))
  • 範圍 [firstlast) 的元素 elem 未根據表示式 bool(comp(elem, value))!bool(comp(value, elem)) 進行 劃分

目錄

[edit] 引數

first, last - 定義要檢查的元素已分割槽範圍的迭代器對。
value - 用於比較元素的數值
comp - 二元謂詞,如果第一個引數排在第二個引數之前,則返回true

謂詞函式的簽名應等效於以下內容:

 bool pred(const Type1 &a, const Type2 &b);

儘管簽名不需要包含 const &,但函式不得修改傳遞給它的物件,並且必須能夠接受型別為 (可能為 const) Type1Type2 的所有值,而不論 值類別(因此,不允許使用 Type1 &,除非對於 Type1,移動等價於複製,否則也不允許使用 Type1(C++11 起))。
型別 Type1Type2 必須使得型別 T 的物件可以隱式轉換為 Type1Type2,並且型別 ForwardIt 的物件可以被解引用然後隱式轉換為 Type1Type2

型別要求
-
ForwardIt 必須滿足 LegacyForwardIterator 的要求。
-
Compare 必須滿足 BinaryPredicate 的要求。不要求它滿足 Compare

[edit] 返回值

如果找到與 value 等價的元素,則返回 true,否則返回 false

[edit] 複雜度

給定 Nstd::distance(first, last)

1) 最多 log2(N)+O(1) 次使用 operator<(C++20 前)std::less{}(C++20 起)value 進行比較。
2) 最多 log2(N)+O(1) 次應用比較器 comp

但是,如果 ForwardIt 不是 LegacyRandomAccessIterator,則迭代器增量的次數與 N 成線性關係。

[edit] 注意

儘管 std::binary_search 只要求 [firstlast) 是已劃分的,但此演算法通常用於 [firstlast) 已排序的情況,以便二分查詢對於任何 value 都是有效的。

std::binary_search 僅檢查是否存在等價元素。要獲取指向該元素(如果存在)的迭代器,應改用 std::lower_bound

特性測試 標準 特性
__cpp_lib_algorithm_default_value_type 202403 (C++26) 演算法的列表初始化 (1,2)

[edit] 可能的實現

另請參閱 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)));
}

[edit] 示例

#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

[edit] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 270 C++98 Compare 需要滿足 比較,且 T 需要
可小於比較的(需要嚴格弱序)
只需要分割槽;
允許異構比較
LWG 787 C++98 最多允許 log2(N)+2 次比較 更正為 log2(N)+O(1)

[edit] 另請參閱

返回與特定鍵匹配的元素範圍
(函式模板) [編輯]
返回一個指向第一個不小於給定值的元素的迭代器
(函式模板) [編輯]
返回一個指向第一個大於某個值的元素的迭代器
(函式模板) [編輯]
判斷一個元素是否存在於部分有序的範圍中
(演算法函式物件)[編輯]