布尔数组的排列

时间:2016-10-05 01:13:58

标签: c arrays algorithm permutation

如果我有一个 n 长度的布尔值数组,我如何迭代数组的所有可能的排列?

例如,对于大小为3的数组,有八种可能的排列:

[0,0,0]
[0,0,1]
[0,1,0]
[0,1,1]
[1,0,0]
[1,0,1]
[1,1,0]
[1,1,1]

P.S。我在C工作,虽然我不一定要寻找特定于语言的答案。只是试图找到一个有效的算法,用大型数组和许多可能的排列来做到这一点。

4 个答案:

答案 0 :(得分:4)

实施"添加1"二进制:

#include <stdio.h>

void add1(int *a, int len) {
  int carry = 1;
  for (int i = len - 1; carry > 0 && i >= 0; i--) {
    int result = a[i] + carry;
    carry = result >> 1;
    a[i] = result & 1;
  }
}

void print(int *a, int len) {
  printf("[");
  for (int i = 0; i < len; i++) {
    if (i > 0) printf(",");
    printf("%d", a[i]);
  }
  printf("]\n");
}

int main(void) {
  int a[3] = { 0 };
  int n = sizeof a / sizeof a[0];
  for (int i = 0; i < (1 << n); i++) {
    print(a, n);
    add1(a, n);
  }
}

编译并运行:

$ gcc foo.c -o foo
$ ./foo
[0,0,0]
[0,0,1]
[0,1,0]
[0,1,1]
[1,0,0]
[1,0,1]
[1,1,0]
[1,1,1]

答案 1 :(得分:2)

为长度为n的向量做一般C语言解决方案(问题标签为C)你可以使用整数变量的二进制表示i:[0,2 ^ n)其中n是数组的长度和 single 循环使用按位运算符迭代所有向量。

答案 2 :(得分:1)

如果你确实需要数组的每个排列。一个更干净的方法可以是 std :: next_permutation()

do{
    std::cout<<v[0]<<" "<<v[1]<<" "<<v[2]<<" "<<v[3]<<std::endl;
}

while(std::next_permutation(v.begin(),v.end()));

理论复杂性将与&#34;添加1&#34;或其他方法。另外,只有STL会为您完成工作。

答案 3 :(得分:0)

使用GMP可以使这更容易一些,特别是如果你真的不需要实际的数组,只需要测试一下这些内容:

#include <gmp.h>

...
int numbits = 3;  // Insert whatever you want
mpz_t curperm;
mpz_init(curperm);

for (; mpz_sizeinbase(curperm, 2) <= numbits; mpz_add_ui(curperm, curperm, 1)) {
    ... test specific bits w/mpz_tstbit(curperm, #) instead of array check of curperm[#] ...
}

mpz_clear(curperm);