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

履歴 編集

function template
<algorithm>

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

namespace std::ranges {
  template<bidirectional_iterator I, sentinel_for<I> S, class Comp = ranges::less, class Proj = identity>
    requires sortable<I, Comp, Proj>
  constexpr prev_permutation_result<I> next_permutation(I first, S last, Comp comp = {}, Proj proj = {});             // (1)

  template<bidirectional_range R, class Comp = ranges::less, class Proj = identity>
    requires sortable<iterator_t<R>, Comp, Proj>
  constexpr prev_permutation_result<borrowed_iterator_t<R>> next_permutation(R&& r, Comp comp = {}, Proj proj = {});  // (2)
}

概要

与えられた時点の[first, last)の範囲を起点の順列として、辞書順によるその前の順列を生成する。

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

効果

[first, last)の範囲を前の順列に変換する。

比較 invoke(comp,invoke(proj, *i),invoke(proj, *j)) によって辞書順に並んでいる全ての順列の集合があると仮定すると、前の順列が発見される。

戻り値

prev_permutation_result {
  .in = last,
  .found = 前の順列が存在する場合は true、そうでなければ false,
}

計算量

高々(last - first)/2回の要素の交換

備考

全ての順列を取得したい場合は、この関数に最初に与える範囲が、降順にソート済みになっていること。

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

void print(const std::vector<int>& v)
{
  for (int x : v) {
    std::cout << x << " ";
  }
  std::cout << std::endl;
}

int main ()
{
  // 降順にソート済みの入力
  std::vector<int> v = {3, 2, 1};

  do {
    print(v);
  } while (std::ranges::prev_permutation(v).found);
}

出力

3 2 1 
3 1 2 
2 3 1 
2 1 3 
1 3 2 
1 2 3 

関連項目

バージョン

言語

  • C++20

処理系

参照