名前空間
変種
操作

std::partition

From cppreference.com
< cpp‎ | algorithm
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとRangeアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
実行ポリシー (C++17)
シーケンスを変更しない操作
一括操作
(C++17)
検索操作
(C++11)                (C++11)(C++11)

シーケンスを変更する操作
コピー操作
(C++11)
(C++11)
スワップ操作
変換操作
生成操作
削除操作
順序変更操作
(C++17まで)(C++11)
(C++20)(C++20)
サンプリング操作
(C++17)

ソートおよび関連操作
パーティション操作
partition
(C++11)  
ソート操作
二分探索操作
(パーティション化された範囲)
集合操作 (ソート済み範囲)
マージ操作 (ソート済み範囲)
ヒープ操作
最小/最大操作
(C++11)
(C++17)
辞書順比較操作
順列操作
Cライブラリ
数値演算
未初期化メモリに対する操作
 
ヘッダー <algorithm> で定義
template< class ForwardIt, class UnaryPred >
ForwardIt partition( ForwardIt first, ForwardIt last, UnaryPred p );
(1) (C++20 以降 constexpr)
template< class ExecutionPolicy, class ForwardIt, class UnaryPred >

ForwardIt partition( ExecutionPolicy&& policy,

                     ForwardIt first, ForwardIt last, UnaryPred p );
(2) (C++17以降)
1) first から last までの範囲の要素を並べ替えます。この並べ替えは、述語 ptrue を返すすべての要素が、述語 pfalse を返すすべての要素の前に来るように行われます。要素の相対的な順序は保持されません。
2) (1) と同じですが、policy に従って実行されます。
このオーバーロードは、以下のすべての条件が満たされた場合にのみオーバーロード解決に参加します。

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 の型が Swappable ではない(C++11まで)ForwardItValueSwappable ではない(C++11以降)場合、動作は未定義です。

目次

[編集] パラメータ

first, last - 並べ替える要素の 範囲 を定義するイテレータのペア
policy - 使用する 実行ポリシー
p - 要素が他の要素よりも前に配置されるべき場合に ​true を返す単項述語。

p(v) の評価結果は、すべての引数 vVTForwardIt の値型、VT は `const` の場合もある)に対して bool に変換可能でなければなりません(値カテゴリに関係なく)。また、v を変更してはなりません。したがって、パラメータ型として VT& は許可されません。また、VT も許可されません(ただし、`VT` においてムーブがコピーと同等な場合を除く)(C++11以降)

型要件
-
ForwardItLegacyForwardIterator の要件を満たさなければなりません。
-
UnaryPredPredicate の要件を満たさなければなりません。

[編集] 戻り値

2番目のグループの最初の要素へのイテレータ。

[編集] 計算量

std::distance(first, last)N とする

1) N 回の p の適用。
ForwardItLegacyBidirectionalIterator の要件を満たす場合、最大 N/2 回のスワップ。それ以外の場合は最大 N 回のスワップ。
2) O(N) 回の p の適用。
O(N·log(N)) 回のスワップ。

[編集] 例外

テンプレートパラメータ ExecutionPolicy を持つオーバーロードは、次のようにエラーを報告します。

  • アルゴリズムの一部として呼び出された関数の実行が例外をスローし、ExecutionPolicy標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他の ExecutionPolicy の場合、動作は実装定義です。
  • アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。

[編集] 実装例

C++11 との互換性を保ちながら、オーバーロード (1) を実装します。

template<class ForwardIt, class UnaryPred>
ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPred p)
{
    first = std::find_if_not(first, last, p);
    if (first == last)
        return first;
 
    for (auto i = std::next(first); i != last; ++i)
        if (p(*i))
        {
            std::iter_swap(i, first);
            ++first;
        }
 
    return first;
}

[編集]

#include <algorithm>
#include <forward_list>
#include <iostream>
#include <iterator>
#include <vector>
 
template<class ForwardIt>
void quicksort(ForwardIt first, ForwardIt last)
{
    if (first == last)
        return;
 
    auto pivot = *std::next(first, std::distance(first, last) / 2);
    auto middle1 = std::partition(first, last, [pivot](const auto& em)
    {
        return em < pivot;
    });
    auto middle2 = std::partition(middle1, last, [pivot](const auto& em)
    {
        return !(pivot < em);
    });
 
    quicksort(first, middle1);
    quicksort(middle2, last);
}
 
int main()
{
    std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::cout << "Original vector: ";
    for (int elem : v)
        std::cout << elem << ' ';
 
    auto it = std::partition(v.begin(), v.end(), [](int i) {return i % 2 == 0;});
 
    std::cout << "\nPartitioned vector: ";
    std::copy(std::begin(v), it, std::ostream_iterator<int>(std::cout, " "));
    std::cout << "* ";
    std::copy(it, std::end(v), std::ostream_iterator<int>(std::cout, " "));
 
    std::forward_list<int> fl {1, 30, -4, 3, 5, -4, 1, 6, -8, 2, -5, 64, 1, 92};
    std::cout << "\nUnsorted list: ";
    for (int n : fl)
        std::cout << n << ' ';
 
    quicksort(std::begin(fl), std::end(fl));
    std::cout << "\nSorted using quicksort: ";
    for (int fi : fl)
        std::cout << fi << ' ';
    std::cout << '\n';
}

実行結果の例

Original vector: 0 1 2 3 4 5 6 7 8 9 
Partitioned vector: 0 8 2 6 4 * 5 3 7 1 9 
Unsorted list: 1 30 -4 3 5 -4 1 6 -8 2 -5 64 1 92 
Sorted using quicksort: -8 -5 -4 -4 1 1 1 2 3 5 6 30 64 92

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
LWG 498 C++98 std::partitionfirst
lastLegacyBidirectionalIterator であることを要求していました。
単に要求していたのは
LegacyForwardIterator
LWG 2150 C++98 std::partition は、1つの要素を
満足する要素の前に配置することを要求していました。
修正されました。
要件

[編集] 関連項目

範囲が指定された述語によってパーティション化されているかどうかを判断する
(関数テンプレート) [編集]
相対的な順序を維持しながら要素を2つのグループに分割する
(関数テンプレート) [編集]
要素の範囲を2つのグループに分割する
(アルゴリズム関数オブジェクト)[編集]
English 日本語 中文(简体) 中文(繁體)