C++で文字列の辞書式順序における次の順列を生成する方法
本記事では、C++を使って文字列の辞書式順序における次の順列を生成する方法を解説します。
辞書式順序の次の順列とは?
辞書式順序における「次の順列」とは、現在の順列よりも辞書式に大きい順列の中で、最も小さいものを指します。たとえば、「ACB」の次の順列は「BAC」です。
ただし、すべての文字列に次の順列が存在するわけではありません。たとえば「BBB」や「DCBA」のように、すでに降順に並んでいる(それ以上大きい並び替えが存在しない)場合には、次の順列はありません。
next_permutation() 関数を使う
C++では、<algorithm>ヘッダーに用意されている next_permutation() 関数を使用することで、この処理を簡単に実装できます。
この関数は、指定した範囲の要素をその場で(in-placeで)次の順列に並べ替えます。戻り値としては、次の順列が存在すれば true を、存在しなければ false を返します。なお、次の順列が存在しない場合は、範囲が昇順(最初の順列)に並べ替えられる点にも注意してください。
サンプルコード
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
string s = "DBAC";
for(int i = 0; i < 5; i++) {
bool val = next_permutation(s.begin(), s.end());
if (val == false) {
cout << "No next permutation" << endl;
break;
} else
cout << "Next: " << s << endl;
}
}
実行結果
Next: DBCA Next: DCAB Next: DCBA No next permutation
コードの解説
このプログラムでは、初期値として「DBAC」という文字列を用意し、ループ内で next_permutation() を繰り返し呼び出しています。
- 1回目:「DBAC」→「DBCA」(Dを固定し、BACの部分を並べ替え)
- 2回目:「DBCA」→「DCAB」
- 3回目:「DCAB」→「DCBA」
- 4回目:「DCBA」は完全な降順のため、次の順列が存在せず
falseが返され、メッセージを表示してループを終了します。
このように、next_permutation() を活用すれば、自前で複雑なアルゴリズムを実装することなく、順列の全列挙や次の順列の取得を簡潔なコードで実現できます。競技プログラミングや組み合わせ問題の求解などでも頻繁に活用される便利な関数です。
-
C++で醜い数(Ugly Number)を求めるアルゴリズムと実装方法
醜い数(Ugly Number)とは醜い数(Ugly Number)とは、素因数が2、3、5のみで構成される正の整数のことです。1から15までの範囲には、1、2、3、4、5、6、8、9、10、12、15の合計11個の醜い数が存在します。一方、7、11、13はそれ自体が素数であるため醜い数には該当しません。また、14は素因数に7を含むため、醜い数とはみなされません。例として、10番目の醜い数を求めると、その値は12になります。アルゴリズムの考え方この問題は、3つのインデックス(ポインタ)を使った動的計画法的なアプローチで効率よく解けます。すでに求めた醜い数に対して、それぞれ2倍、3倍、5倍した値
-
Pythonで実装する「次の順列(Next Permutation)」アルゴリズムの解説
「次の順列(Next Permutation)」とは、数列を辞書式順序で次に大きい並びへと並べ替える操作のことです。もし次に大きい順列が存在しない場合(数列が降順に並んでいる場合)は、最も小さい順列、つまり昇順にソートされた状態へと並べ替えます。この処理では余分なメモリを使用せず、配列そのものを直接書き換える「インプレース」方式で実装する必要があります。 入力と出力の対応は以下のようになります。 1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1 アルゴリズムの手順 found := False、i := 配列の長さ − 2 で初期化する i >= 0 の間