2011-01-26 23 views
2

配列内の複数の数値範囲から順列を生成する必要があります。複数の数値範囲の順列

using namespace std; 

int generatePermutations(vector<int> &myVector, vector<vector<int> > &swappable) { 
    int i = 0, s = 0; 
    for (s = 0; s < swappable.size(); s++) { 
     do { 
      for (i = 0; i < myVector.size(); i++) { 
       printf("%i ", myVector[i]); 
      } 
      printf("\n"); 
      swappable.pop_back(); 
      generatePermutations(myVector, swappable); 
     } while (next_permutation(myVector.begin()+swappable[s][0], 
       myVector.begin()+swappable[s][1])); 
    } 
} 

int main() { 
    vector<int> myArray; 
    myArray.resize(6); 
    myArray[0] = 0; 
    myArray[1] = 1; 
    myArray[2] = 2; 
    myArray[3] = 3; 
    myArray[4] = 4; 
    myArray[5] = 5; 

    // Swappable positions (0 - first, 1 - last) 
    vector<vector<int> > swappable; 
    swappable.resize(2); 
    swappable[0].resize(2); 
    swappable[0][0] = 1; swappable[0][1] = 3; 
    swappable[1].resize(2); 
    swappable[1][0] = 4; swappable[1][1] = 6; 
    generatePermutations(myArray, swappable); 

    return 0; 
} 

上記の例では、このようなものを生成する必要があります

0 1 2 3 4 5 
0 2 1 3 4 5 
0 1 2 3 5 4 
0 2 1 3 5 4 

をしかし、それは、この生成します

0 1 2 3 4 5 
0 1 2 3 4 5 
+0

「交換可能」とは何ですか?なぜあなたのコードにコメントはありませんか? –

+0

コメントが追加されました。私は順列を生成する必要があります間の最初と最後の位置を保持するためです。 –

+0

デバッガでコードをステップ実行して、*常に*同じ結果を表示する理由を確認しましたか? –

答えて

2

が、私はそれがスワップ可能なスワップすることができる範囲のセットで取りますか?だから、[[1,3]、[4,6]]は[1,3](インデックス1と2)のすべてがその範囲で入れ替えることができることを意味し、同様に[4,6]範囲が重複しないことも真実ですか?ここで

How does this look:

typedef vector<vector<int> >::const_iterator SwappableIter; 
void generatePermutations(vector<int> &data, 
          SwappableIter begin, SwappableIter end) 
{ 
    if (begin == end) { 
    print(data); 
    } 
    else { 
    vector<int>::iterator start = data.begin() + (*begin)[0], 
     stop = data.begin() + (*begin)[1]; 
    sort(start, stop); 
    do { 
     generatePermutations(data, begin + 1, end); 
    } while (next_permutation(start, stop)); 
    } 
} 
+0

はい、範囲は重複しません。 –

+1

'swappable'が範囲のベクトルであると想定されている場合、ネストされたベクトルではなく' std :: pair'またはカスタム 'struct'を使用してください。 –

+0

はい、ペアが良いでしょう。私は私の例の質問からタイプを守った。 –

0

(壊れている)あなたの生成アルゴリズムを少し変更したバージョンです。

int generatePermutations(vector<int> &myVector, vector<vector<int> >& swappable) { 
    do 
    { 
    do 
    { 
     print(myVector); 
     // generate permutations of the second segment 
    } while(next_permutation(myVector.begin() + swappable[1][0], myVector.begin() + swappable[1][1])); 

    // re-sort the second segment 
    sort(myVector.begin() + swappable[1][0], myVector.begin() + swappable[1][1]); 

    // calculate permutation of first segment 
    } while(next_permutation(myVector.begin() + swappable[0][0], myVector.begin() + swappable[0][1])); 
} 

EDIT:組み合わせを生成するために、今、固定、2つのだけの範囲で動作し、上記のフレッドのソリューションは、よりスケーラブルな..です

+0

これはうまく拡張できません。例えばswappable.size()== 10. –

+0

@Fred、true .... – Nim

+0

これも[動作しません](http://ideone.com/qTuew)。 –

0

あなたは問題のために、一見正しい反復解法を作成しますが、それぞれにしています反復では、ベクトルswappableから要素を削除し、再帰呼び出しを行います。
myVectorswappableはいずれも非const参照で渡されているため、これらの再帰呼び出しは実際に置換を生成する前にswappableベクトルの内容を破棄します。

ジャストライン

swappable.pop_back(); 
generatePermutations(myVector, swappable); 

を削除して、コードが仕事に開始する必要があります。

+0

問題のコードは、あなたが言及した2つの行を削除した後、動作しません。 –

+0

@Fred Nurk:どのように動作しないか説明するケア?あるいは、 '#include'ステートメントがないことを意味しますか?必要な '#include'を追加してコードを実行すると、コメントした行が@Radekが期待していたものと似た結果になります。 –

+0

http://ideone.com/4GHv0を参照してください。最後の警告、4つの出力回線に1つの回線がどのように複製されているか、および1つの回線が予期された出力からどのように失われているかにより、UBに注意してください。 (そして、ところで、私のダウンボートではなかった;私はdownvoteしないでください。) –