2016-03-24 6 views
-2
int i = 0; 
for(; i<size-1; i++) { 
    int temp = arr[i]; 
    arr[i] = arr[i+1]; 
    arr[i+1] = temp; 
} 

ここでは、配列の最初の位置から始めました。ループの後でforループを再度実行し、forループが配列の次の位置で開始する必要がある場合はどうなりますか?C++の 'forループ'の初期化子を変更

から第for loopを開始するための評価:配列[0]

第2の反復:配列[1]

第3の反復:配列について

:[2]

例アレイ。 1 2 3 4 5

i = 0:2 1 3 4 5、2 3 1 4 5、2 3 4 1 5、2 3 4 5 1

i = 1:1 3 2 4 5、1 3 4 2 5、1 3 4 5 2など。

+3

これはネストされたforループと呼ばれます。 – callyalater

+0

詳細:私が働いているコード:[リンク](http://pastebin.com/zqeP8SRm) –

+2

あなたは何をしていますか?あなたは配列またはリストが前にソートされているかどうかをテストする方法を求めました:http://stackoverflow.com/questions/35989316およびhttp://stackoverflow.com/questions/35867423 - 配列のすべての可能な順列を探していますか?ソートされたもの? – CiaPan

答えて

2

内部ループが外部ループのイテレータ値にアクセスする機能を含め、ループを互いにネストすることができます。したがって:

for(int start = 0; start < size-1; start++) { 
    for(int i = start; i < size-1; i++) { 
     // Inner code on 'i' 
    } 
} 

は、あなたがあなたのリストを介して行っているまでこれiのために高い初期値を繰り返し、増加start値を使用してループを繰り返します。

1

与えられた長さの配列要素のすべての可能な順列を生成するルーチンがあるとします。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

注:

  1. 入力サイズが非常に小さい場合は、妥当な時間内に動作する可能性があります。置換の数は配列の長さの階乗関数であり、指数関数的に速くなり、実際にはBIGテスト数になります。
  2. ルーチンには短い戻り値がありません。第1または第2順列が正しい結果であっても、ルーチンはの残りの部分をすべて実行します。不要なテストもあります。もちろん、リピートパスを追加して反復処理を中断することはできますが、コードをいくらか醜いものにするでしょう。ルーチンは平均してn!/ 2のテストをしなければならないので、それは大きな利益をもたらさないだろう。
  3. 生成された各順列は、再帰の最後のレベルで深く現れる。正しい結果をテストするには、ProcessThePermutationProcessAllPermutationsから呼び出す必要があります。そのため、呼び出し先を他の関数に置き換えることは困難です。呼び出し元関数は、テスト/処理/その他の別のメソッドが必要になるたびに変更する必要があります。または、処理関数( 'コールバック')へのポインタを提供し、呼び出しが発生する場所まで、すべての再帰を介してそれをプッシュダウンする必要があります。これは、コンテキストオブジェクトの仮想関数によって間接的に行われる可能性があるため、見た目はすばらしくなりますが、追加データを再帰呼び出しに渡すオーバーヘッドは避けられません。
  4. ルーチンにはもう一つ興味深いプロパティがあります。データ値に依存しません。配列の要素は決して比較されません。これは時には利点になるかもしれません。ルーチンは、比較できないオブジェクトであっても、あらゆる種類のオブジェクトを並べ替えることができます。一方、それは重複を検出することができないので、等しい項目の場合には、繰り返しの結果が出ます。縮退したすべてのケースでは、nと等しいアイテムは、結果はです!が等しい配列。

並べ替えられたものを検出するためにすべての順列を生成する方法を尋ねるなら、私は答えなければなりません:しないでください。
効果的なソートアルゴリズムを習得してください。

+0

それは私が実際に探しているものです。並べ替えられたものを検出するためにすべての並べ替えを生成します。 –

関連する問題