2011-12-23 14 views
4

可能性の重複を要素のすべての組み合わせを生成します。
How can I create cartesian product of vector of vectors?は、2Dベクトルで

私は2Dベクトルの要素のすべての組み合わせを生成する方法を考え出すいくつかの論理的な問題を抱えています。ここでは、2Dベクトルを作成します。どちらの次元のサイズも想定できません。

#include <iostream> 
#include <vector> 

using namespace std; 

int main() { 
    srand(time(NULL)); 
    vector< vector<int> > array; 

    // This creates the following: 
    // array[0]: {0, 1, 2} 
    // array[1]: {3, 4, 5, 9} 
    // array[2]: {6, 7, 8} 
    for(int i=0; i<3; i++) { 
    vector<int> tmp; 
    tmp.push_back((i*3)+0); tmp.push_back((i*3)+1); tmp.push_back((i*3)+2); 
    if(i==1) 
     tmp.push_back((i*3)+6); 
    array.push_back(tmp); 
    } 
} 

次のようにベクトルを作成した後、私は出力にすべての可能な組み合わせを希望は:

comb[0] = {0, 3, 6} 
    comb[1] = {0, 3, 7} 
    comb[2] = {0, 3, 8} 
    comb[3] = {0, 4, 6} 
    comb[4] = {0, 4, 7} 
    comb[x] = {...} 

は、しかし、私は、これを適切に行うためにループ構造を概念化する方法トラブルを抱えています各サブアレイの要素は未知/動的です。

EDIT 1:3つの配列があると想定できません。 array.size()があります;)

+0

私はおそらくあなたを助けることができますが、実際には何を意味するのかを数学的に説明してください(http://www.mathsisfun.com/combinatorics/combinations-permutations.html)。 – Kos

+0

それはおそらく板金製品ですか? 5つの配列ABCDEを入力として、aがAから、bがBなどから、すべての5タプル(abcde)を期待しますか? – Kos

答えて

5

未知のサイズの最も簡単な方法は再帰です。

void combinations(vector<vector<int> > array, int i, vector<int> accum) 
{ 
    if (i == array.size()) // done, no more rows 
    { 
     comb.push_back(accum); // assuming comb is global 
    } 
    else 
    { 
     vector<int> row = array[i]; 
     for(int j = 0; j < row.size(); ++j) 
     { 
      vector<int> tmp(accum); 
      tmp.push_back(row[j]); 
      combinations(array,i+1,tmp); 
     } 
    } 
} 

は当初i = 0と空accumと呼んでいます。

+0

、完璧に働いてくれてありがとう! – gnychis

2

あなたは3つの配列を持っていますよね?それぞれのサイズが異なり、すべての組み合わせが必要です。もしそうなら、これはあなたを助ける必要があります。

擬似コード:私はあなたがCにそれを再書き込みすることを願って

for(i=0; i<size(array0), i++) { 
    for(j=0; j<size(array1), j++) { 
     for(k=0; k<size(array2), k++) { 
      print("{array0[i], array1[j], array2[k]} \n"); 

     } 
    } 
} 

++コード

EDIT:これは、配列

、任意の数のために働く必要があります

最初のforは印刷中で、2番目の文字は配列のインデックスを移動します(オーバーフローが気になる)

もう一度擬似コード:

comb = 0; 
stop = false; 
while(!stop) { 
    output("Combination["+comb+"] = {"); 
    for(i = 0; i < num_of_arrays; i++) { 
    index = index_array[i]; 
    output(array[i][index]); // assume this function takes care about right formatting 

    } 
    output("}\n"); 

    index_array[num_of_arrays-1]++; 

    for(i = num_of_arrays-1; i >= 0; i--) { 
    index = index_array[i] 
    if(index == size(array[i]) { 
     if(i == 0) 
      stop = true; 
     else { 
      index_array[i] = 0; 
      index_array[i-1]++; 
     } 
    } 
    } 
    comb++; 
} 

希望します。

+0

だからトリック/チャレンジは3つの配列しかないとは思えません。そうでなければ私はあなたのソリューションに完全に同意します。 – gnychis

+1

編集後のコードを参照してください。 – SlavaNov

+0

index_array []とは何ですか?どのように初期化されますか? – gnychis

関連する問題