与えられた長さの配列要素のすべての可能な順列を生成するルーチンがあるとします。nルーチンを仮定して、すべて処理した後n!順列の場合、最初の順序で配列の項目をnのままにします。
質問:配列のすべての可能な並べ替えを(n + 1)要素で行うためのルーチンを作成するにはどうすればよいですか?
回答:
初期N要素のすべての順列を生成し、各タイム・プロセス全体のアレイ。このように私たちはすべてを処理しました!同じ最後の項目を持つ順列。
は今、それらのいずれかで(N + 1) -st項目を入れ替えるNと繰り返しn個要素を置換する - 私たちは別のn個を入手します!新しい最後のアイテムを持つ順列。
nの要素は以前の順序で残されているため、最後の要素を最初の場所に戻し、配列の最後に配置する要素をもう1つ選択します。並べ替えを繰り返すnアイテム。
など。
各呼び出しの後、ルーチンはn -items配列を初期状態のままにします。 n + 1にこのプロパティを保持するには、(n + 1)の反復nの後に同じ要素が最終的に配列の最後に配置されるようにする必要があります。順列。
この
は、あなたがそれを行うことができる方法である。
void ProcessAllPermutations(int arr[], int arrLen, int permLen)
{
if(permLen == 1)
ProcessThePermutation(arr, arrLen); // print the permutation
else
{
int lastpos = permLen - 1; // last item position for swaps
for(int pos = lastpos; pos >= 0; pos--) // pos of item to swap with the last
{
swap(arr[pos], arr[lastpos]); // put the chosen item at the end
ProcessAllPermutations(arr, arrLen, permLen - 1);
swap(arr[pos], arr[lastpos]); // put the chosen item back at pos
}
}
}
を、ここでルーチンの実行の例です。このアプローチは非常に非効率的であること、しかし、https://ideone.com/sXp35O
注:
- 入力サイズが非常に小さい場合は、妥当な時間内に動作する可能性があります。置換の数は配列の長さの階乗関数であり、指数関数的に速くなり、実際にはBIGテスト数になります。
- ルーチンには短い戻り値がありません。第1または第2順列が正しい結果であっても、ルーチンはの残りの部分をすべて実行します。不要なテストもあります。もちろん、リピートパスを追加して反復処理を中断することはできますが、コードをいくらか醜いものにするでしょう。ルーチンは平均してn!/ 2のテストをしなければならないので、それは大きな利益をもたらさないだろう。
- 生成された各順列は、再帰の最後のレベルで深く現れる。正しい結果をテストするには、
ProcessThePermutation
をProcessAllPermutations
から呼び出す必要があります。そのため、呼び出し先を他の関数に置き換えることは困難です。呼び出し元関数は、テスト/処理/その他の別のメソッドが必要になるたびに変更する必要があります。または、処理関数( 'コールバック')へのポインタを提供し、呼び出しが発生する場所まで、すべての再帰を介してそれをプッシュダウンする必要があります。これは、コンテキストオブジェクトの仮想関数によって間接的に行われる可能性があるため、見た目はすばらしくなりますが、追加データを再帰呼び出しに渡すオーバーヘッドは避けられません。
- ルーチンにはもう一つ興味深いプロパティがあります。データ値に依存しません。配列の要素は決して比較されません。これは時には利点になるかもしれません。ルーチンは、比較できないオブジェクトであっても、あらゆる種類のオブジェクトを並べ替えることができます。一方、それは重複を検出することができないので、等しい項目の場合には、繰り返しの結果が出ます。縮退したすべてのケースでは、nと等しいアイテムは、結果はです!が等しい配列。
並べ替えられたものを検出するためにすべての順列を生成する方法を尋ねるなら、私は答えなければなりません:しないでください。
効果的なソートアルゴリズムを習得してください。
これはネストされたforループと呼ばれます。 – callyalater
詳細:私が働いているコード:[リンク](http://pastebin.com/zqeP8SRm) –
あなたは何をしていますか?あなたは配列またはリストが前にソートされているかどうかをテストする方法を求めました:http://stackoverflow.com/questions/35989316およびhttp://stackoverflow.com/questions/35867423 - 配列のすべての可能な順列を探していますか?ソートされたもの? – CiaPan