std::next_permutation
| ヘッダー <algorithm> で定義 |
||
| template< class BidirIt > bool next_permutation( BidirIt first, BidirIt last ); |
(1) | (C++20 以降 constexpr) |
| template< class BidirIt, class Compare > bool next_permutation( BidirIt first, BidirIt last, Compare comp ); |
(2) | (C++20 以降 constexpr) |
範囲 [first, last) を次の順列に並べ替えます。そのような「次の順列」が存在する場合はtrueを返します。それ以外の場合は、範囲を辞書式で最初の順列に変換し(std::sortを使用した場合と同様)、falseを返します。
*firstの型がSwappableでない(C++11まで)BidirItがValueSwappableでない(C++11以降)場合、動作は未定義です。
目次 |
[編集] パラメータ
| first, last | - | 並べ替える要素の範囲を定義するイテレータのペア |
| comp | - | 比較関数オブジェクト(すなわち、Compareの要件を満たすオブジェクト)。最初の引数が2番目の引数より小さい場合にtrueを返す。 比較関数のシグネチャは、以下と同等でなければならない。 bool cmp(const Type1& a, const Type2& b); シグネチャにconst&は必須ではないが、関数は渡されたオブジェクトを変更してはならず、値カテゴリに関係なく、 |
| 型要件 | ||
-BidirIt は LegacyBidirectionalIterator の要件を満たしている必要があります。 | ||
[編集] 戻り値
新しい順列が古い順列よりも辞書式順序で大きい場合はtrue。falseは、最後の順列に到達し、範囲が最初の順列にリセットされた場合。
[編集] 計算量
std::distance(first, last) を N とする
| N |
| 2 |
[編集] 例外
イテレータ操作または要素のスワップからスローされるすべての例外。
[編集] 可能な実装
template<class BidirIt> bool next_permutation(BidirIt first, BidirIt last) { auto r_first = std::make_reverse_iterator(last); auto r_last = std::make_reverse_iterator(first); auto left = std::is_sorted_until(r_first, r_last); if (left != r_last) { auto right = std::upper_bound(r_first, left, *left); std::iter_swap(left, right); } std::reverse(left.base(), last); return left != r_last; } |
[編集] 備考
順列のシーケンス全体で平均すると、典型的な実装では1回の呼び出しあたり約3回の比較と1.5回のスワップを使用します。
実装(例:MSVC STL)は、イテレータの型がLegacyContiguousIteratorを満たし、その値型のスワップが自明でない特殊メンバ関数もADLで見つかるswapも呼び出さない場合、ベクトル化を有効にできます。
[編集] 例
次のコードは、文字列"aba"の3つの順列すべてを出力します。
#include <algorithm> #include <iostream> #include <string> int main() { std::string s = "aba"; do { std::cout << s << '\n'; } while (std::next_permutation(s.begin(), s.end())); std::cout << s << '\n'; }
出力
aba baa aab
[編集] 関連項目
| (C++11) |
あるシーケンスが別のシーケンスの順列であるかを判断する (関数テンプレート) |
| 要素の範囲の次に小さい辞書順の順列を生成する (関数テンプレート) | |
| (C++20) |
要素の範囲の次に大きい辞書順の順列を生成する (アルゴリズム関数オブジェクト) |