std::nth_element
| ヘッダー <algorithm> で定義 |
||
template< class RandomIt > void nth_element( RandomIt first, RandomIt nth, RandomIt last ); |
(1) | (C++20 以降 constexpr) |
| template< class ExecutionPolicy, class RandomIt > void nth_element( ExecutionPolicy&& policy, |
(2) | (C++17以降) |
template< class RandomIt, class Compare > void nth_element( RandomIt first, RandomIt nth, RandomIt last, |
(3) | (C++20 以降 constexpr) |
| template< class ExecutionPolicy, class RandomIt, class Compare > void nth_element( ExecutionPolicy&& policy, |
(4) | (C++17以降) |
nth_element は、[first, last) の範囲の要素を並べ替えます。並べ替え後、
nthが指す要素は、[first,last)がソートされていた場合にその位置に現れる要素に変更されます。[first,nth)のすべてのイテレータ i と、[nth,last)のすべてのイテレータ j について、次の条件が満たされます。
|
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> が true である。 |
(C++20まで) |
|
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> は true です。 |
(C++20以降) |
次のいずれかの条件が満たされる場合、動作は未定義です。
-
[first,nth)または[nth,last)は有効な範囲ではありません。
|
(C++11まで) |
|
(C++11以降) |
目次 |
[edit] パラメータ
| first, last | - | 部分ソートする要素の範囲を定義するイテレータのペア |
| nth | - | ソートのパーティションポイントを定義するランダムアクセス イテレータ |
| policy | - | 使用する 実行ポリシー |
| comp | - | 比較関数オブジェクト(つまり、Compare の要件を満たすオブジェクト)。最初の引数が2番目の引数より小さい(つまり、前に順序付けられる)場合に true を返します。 比較関数のシグネチャは、以下と同等でなければならない。 bool cmp(const Type1& a, const Type2& b); シグネチャは const& を持つ必要はありませんが、関数は渡されたオブジェクトを変更してはならず、値カテゴリ に関係なく、(おそらく const の) |
| 型要件 | ||
-RandomItはLegacyRandomAccessIteratorの要件を満たす必要がある。 | ||
-CompareはCompareの要件を満たす必要がある。 | ||
[edit] 計算量
N を last - first とした場合
[edit] 例外
ExecutionPolicy というテンプレートパラメータを持つオーバーロードは、次のようにエラーを報告します。
- アルゴリズムの一部として呼び出された関数の実行が例外をスローし、
ExecutionPolicyが 標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他のExecutionPolicyの場合、動作は実装定義です。 - アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。
[edit] 実装例
libstdc++、libc++、および MSVC STL の実装も参照してください。
[edit] 注記
通常、使用されるアルゴリズムはIntroselectですが、他の選択アルゴリズムで適切な平均計算量を持つものも許可されています。
[edit] 例
#include <algorithm> #include <cassert> #include <functional> #include <iostream> #include <numeric> #include <vector> void printVec(const std::vector<int>& vec) { std::cout << "v = {"; for (char sep[]{0, ' ', 0}; const int i : vec) std::cout << sep << i, sep[0] = ','; std::cout << "};\n"; } int main() { std::vector<int> v{5, 10, 6, 4, 3, 2, 6, 7, 9, 3}; printVec(v); auto m = v.begin() + v.size() / 2; std::nth_element(v.begin(), m, v.end()); std::cout << "\nThe median is " << v[v.size() / 2] << '\n'; // The consequence of the inequality of elements before/after the Nth one: assert(std::accumulate(v.begin(), m, 0) < std::accumulate(m, v.end(), 0)); printVec(v); // Note: comp function changed std::nth_element(v.begin(), v.begin() + 1, v.end(), std::greater{}); std::cout << "\nThe second largest element is " << v[1] << '\n'; std::cout << "The largest element is " << v[0] << '\n'; printVec(v); }
実行結果の例
v = {5, 10, 6, 4, 3, 2, 6, 7, 9, 3};
The median is 6
v = {3, 2, 3, 4, 5, 6, 10, 7, 9, 6};
The second largest element is 9
The largest element is 10
v = {10, 9, 6, 7, 6, 3, 5, 4, 3, 2};[edit] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2150 | C++98 | nth の前には、並べ替え後、1つの要素のみが nth の後にある1つの要素以下であることが必要でした。 |
修正されました。 要件 |
| LWG 2163 | C++98 | オーバーロード (1) は要素の比較に operator> を使用していました。 | operator< に変更されました。 |
| P0896R4 | C++98 | [first, nth) および [nth, last)は有効な範囲である必要はありませんでした。 |
未定義の動作 それらのいずれかが無効な場合。 |
[edit] 関連項目
| 範囲内で最大の要素を返す (関数テンプレート) | |
| 範囲内で最小の要素を返す (関数テンプレート) | |
| 要素の範囲をコピーして部分的にソートする (関数テンプレート) | |
| 等しい要素間の順序を維持しながら要素の範囲をソートする (関数テンプレート) | |
| 範囲を昇順にソートする (関数テンプレート) | |
| (C++20) |
与えられた範囲を部分的にソートし、指定された要素によってパーティション化されるようにする (アルゴリズム関数オブジェクト) |