2012-03-06 55 views
3

很多時候,你有一個問題,屬性A可以是真或假,屬性B也可以是真或假,等等。我們想要測試A的每個組合都是正確的,而B是錯誤的,等等。因此,例如,我們可能需要以下列表:在C++中生成組合列表的最簡單方法是什麼?

[true,true,true] 
[true,true,false] 
[true,false,true] 
[true,false,false] 
[false,true,true] 
[false,true,false] 
[false,false,true] 
[false,false,false] 

在Haskell或Python,這可以通過列表的產品功能來完成。

我的問題是,什麼是產生這種最簡單的和/或最快的方法?我一直都是通過將數字轉換爲二進制來完成的,然後將二進制數據轉換爲數組。但是這看起來很麻煩,因爲十進制到二進制轉換並不是完全無關緊要的,我們還需要擔心用前導零填充二進制以正確填充數組。

我已經實現和重新實現這種功能在不同環境下足夠的時間來想,有沒有辦法很簡單,你可以從頭開始實現它在必要的時候 - 沒有真正不必考慮?

回答

5

我不是很確定的代碼,但沿着這些線應該工作。

for(int i = 0; i < 8; i++){ 
    printf("[%s, %s, %s]\n", (i & 0x1)?"True":"False", ((i & 0x2) >> 1)?"True":"False" , ((i & 0x4) >> 2)?"True":"False"); 
} 

我通過數字迭代0到7(分別000至111),並分離各比特以標識布爾值。

+0

更好,謝謝@Loki – 2012-03-07 01:14:59

+0

不需要位移! – vvnraman 2012-03-07 13:26:48

+0

@mwraman,你是對的。這些轉變來自於我在返回0和1時的原始實施。 – 2012-03-07 17:31:00

3

使用遞歸。

void f(x,i,n) { 
    if (i<n) { 
    x[i]=False; 
    f(x,i+1,n); 
    x[i]=True; 
    f(x,i+1,n); 
    } 
    else print(x); 
} 
1

試試這個 -

void allCombinations(int numVars) { 
    for(int i = 0; i < (1<<numVars); i++) { //(1<<n) means 2^n 
     for(int j = 0; j < numVars; j++) { 
      if(i & (1<<j)) { //j-th variable value is true 
       //do something 
      } 
      else { //j-th variable is false 
       //do some other thing 
      } 
     } 
    } 
} 

這種技術被廣泛使用的較量程序員。

-1

最簡單的方法是使用從STL提供next_permutation。以下代碼是從cplusplus.com

// next_permutation 
#include <iostream> 
#include <algorithm> 
using namespace std; 

int main() { 
    int myints[] = {1,2,3}; 

    cout << "The 3! possible permutations with 3 elements:\n"; 

    sort (myints,myints+3); 

    do { 
    cout << myints[0] << " " << myints[1] << " " << myints[2] << endl; 
    } while (next_permutation (myints,myints+3)); 

    return 0; 
} 
+0

這個問題沒有要求所有的排列組合,而是所有可能的二元變量組合。 – 2012-03-07 04:21:12

相關問題