Namespaces
Variants

std:: partition

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
ヘッダー <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 ) 内の要素を、述語 p true を返すすべての要素が、述語 p false を返すすべての要素の前に来るように並べ替える。要素の相対的な順序は保持されない。
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以前) ForwardIt ValueSwappable でない場合 (C++11以降) 、動作は未定義です。

目次

パラメータ

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

p ( v ) は、 VT 型(possibly const)のあらゆる引数 v に対して bool に変換可能でなければならず、 値カテゴリ に関わらず v を変更してはならない。したがって、 VT & のパラメータ型は許可されない 。また、 VT も、 VT に対してムーブがコピーと等価でない限り許可されない (C++11以降) 。 ​

型要件
-
ForwardIt LegacyForwardIterator の要件を満たさなければならない
-
UnaryPred Predicate の要件を満たさなければならない

戻り値

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

計算量

与えられた N std:: distance ( first, last ) として:

1) 正確に N 回の p の適用。
ForwardIt LegacyBidirectionalIterator の要件を満たす場合は最大 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::partition first
last LegacyBidirectionalIterator であることを要求
LegacyForwardIterator のみを要求
LWG 2150 C++98 std::partition p を満たす1つの要素を
p を満たさない1つの要素の前に配置することを要求
要件を修正

関連項目

指定された述語で範囲が分割されているかどうかを判定する
(関数テンプレート)
要素を2つのグループに分割し、相対的な順序を保持する
(関数テンプレート)
要素の範囲を2つのグループに分割する
(アルゴリズム関数オブジェクト)