2012-03-06 70 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

相关问题