std::binary_search
| ヘッダー <algorithm> で定義 |
||
| (1) | ||
template< class ForwardIt, class T > bool binary_search( ForwardIt first, ForwardIt last, |
(C++20 以降 constexpr) (C++26まで) |
|
| template< class ForwardIt, class T = typename std::iterator_traits <ForwardIt>::value_type > |
(C++26以降) | |
| (2) | ||
template< class ForwardIt, class T, class Compare > bool binary_search( ForwardIt first, ForwardIt last, |
(C++20 以降 constexpr) (C++26まで) |
|
| template< class ForwardIt, class T = typename std::iterator_traits <ForwardIt>::value_type, |
(C++26以降) | |
要素 value と等価な要素が、区分された範囲 [first, last) 内に存在するかどうかをチェックします。
|
次のいずれかの条件が満たされる場合、動作は未定義です。
|
(C++20まで) |
|
std::binary_search(first, last, value, std::less{}) と同等です。 |
(C++20以降) |
[first, last) 内のいずれかのイテレータ iter について、!bool(comp(*iter, value)) && !bool(comp(value, *iter)) が true の場合、true を返します。それ以外の場合は false を返します。[first,last)の任意の要素 elem について、bool(comp(elem, value)) は !bool(comp(value, elem)) を含意しません。[first,last)の要素 elem は、式 bool(comp(elem, value)) および !bool(comp(value, elem)) に関して 区分 されていません。
目次 |
[編集] Parameters
| first, last | - | 調査する要素の分割された範囲を定義するイテレータのペア |
| value | - | 要素と比較する値 |
| comp | - | 第一引数が第二引数より前に順序付けられる場合に `true` を返す二項述語。 述語関数のシグネチャは、以下と同等である必要がある。 bool pred(const Type1 &a, const Type2 &b); シグネチャは const & を持つ必要はないが、関数は渡されたオブジェクトを変更してはならず、値カテゴリに関わらず、(おそらく const の) |
| 型要件 | ||
-ForwardIt は LegacyForwardIterator の要件を満たさなければなりません。 | ||
| -`Compare` は BinaryPredicate の要件を満たす必要があります。 Compare を満たす必要はありません。 | ||
[編集] Return value
true 要素 value と等価な要素が見つかった場合、false それ以外の場合。
[編集] Complexity
std::distance(first, last) を N とする
ただし、ForwardIt が LegacyRandomAccessIterator でない場合、イテレータのインクリメント回数は N に対して線形になります。
[編集] Notes
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) のためのリスト初期化 |
[編集] Possible implementation
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))); } |
[編集] Example
#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
[編集] Defect reports
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 270 | C++98 | Compare は Compare を満たす必要があり、`T` はLessThanComparable (厳密弱順序が必要) である必要がありました。 |
分割のみが必要。 異種比較が許可される。 |
| LWG 787 | C++98 | 最大 log2(N)+2 回の比較が許可されていました。 | log2(N)+O(1) に修正されました。 |
[編集] See also
| 特定のキーに一致する要素の範囲を返す (関数テンプレート) | |
| 与えられた値より小さくない最初の要素へのイテレータを返す (関数テンプレート) | |
| 特定の値より大きい最初の要素へのイテレータを返す (関数テンプレート) | |
| (C++20) |
部分的に順序付けられた範囲に要素が存在するかどうかを判断する (アルゴリズム関数オブジェクト) |