最終更新日時(UTC):
が更新

履歴 編集

function template
<algorithm>

std::ranges::stable_partition(C++20)

namespace std::ranges {
  // (1)
  template<bidirectional_iterator I, sentinel_for<I> S, class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
    requires permutable<I>
  subrange<I> stable_partition(I first, S last, Pred pred, Proj proj = {});

  // (2)
  template<bidirectional_range R, class Proj = identity, indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
    requires permutable<iterator_t<R>>
  borrowed_subrange_t<R> stable_partition(R&& r, Pred pred, Proj proj = {});
}

概要

与えられた範囲を相対順序を保ちながら条件によって区分化する。

  • (1): イテレータペアで範囲を指定する
  • (2): 範囲を直接指定する

効果

[first,last) 内にある pred を満たす全ての要素を、pred を満たさない全ての要素より前に移動させる。

戻り値

{i, last}

ただし、[first,i) 内にあるイテレータ j について pred(*j) != false を満たし、[i,last) 内にあるイテレータ k について pred(*k) == false を満たすようなイテレータ(つまり、区分化された境界を指すイテレータ)を i とする。

条件を満たす・満たさない両グループ内での要素間の相対順序は保たれる。

計算量

N = last - firstとして説明する。

  • (1) : 最大でN log N回 swap が行われるが、余分なメモリを使って構わないのであれば線形回数の swap になる。それに加えて、正確にN回だけ述語が適用される
  • (2) : O(N log N) 回の swap に加え、述語が O(N) 回適用される

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
  std::vector<int> v = {1, 2, 3, 4, 5};

  // 偶数グループと奇数グループに分ける
  std::ranges::stable_partition(v, [](int x) { return x % 2 == 0; });

  for (int x : v) {
   std::cout << x << std::endl;
  }
}

出力

2
4
1
3
5

バージョン

言語

  • C++20

処理系

参照