如果给出1的数量,我怎样才能找到所有可能的二进制表示?

时间:2011-07-29 16:22:19

标签: pseudocode

给定N作为位数,K作为1的数量,如何生成包含K个和N-k个零的所有二进制表示?

换句话说,我有:

N=4 //number of bits
K=2 //number of ones

包含N位,K个和N-K个零的所有可能的二进制值是:

1100
1010
1001    
0110
0101
0011
到目前为止,我什么都没有。我不是要求代码。我只想问最好的方法吗?一个算法?伪代码?也许是讨论?

编辑:我要求代码/伪代码来解决问题...而不是数学公式......

12 个答案:

答案 0 :(得分:5)

记住数学课的组合和排列吗?

谷歌它找到方程式,使用: http://www.mathsisfun.com/combinatorics/combinations-permutations-calculator.html快速计算:)

答案 1 :(得分:4)

我会说'递归':

假设f(K,N)为您提供了所有可能的字符串:

def f(K,N):
  if N=0:
    return []
  else if (K=N):
    return [ones(K)]
  else 
    union(concat('1',f(K-1,N-1)), concat('0',(K,N-1)))

使用:

def concat(c,vec):
  retval= []
  for x in vec:
    retval.append(c&x) //& is the concatenation operator
  return retval

ones(K)返回由K“1”

组成的字符串

union(x,y)合并两个向量x和y

答案 2 :(得分:1)

这更像是一个数学问题。你正在寻找一个N长度的字符串,其中K为1.所以你有N choose K,如果内存服务的话是N!/K!*(N-K)! - 其他如果我错了请更正!

答案 3 :(得分:1)

您想要查找一组N个元素的大小为K的所有子集,例如S = {1,2,...,N}。你可以很容易地递归表达:

S的大小K的子集是{1,2,...,N-1}的大小K的子集,或者是{N}的联合和{1,2,...,N-1}的大小K-1的子集。 (这正是二项式系数的递归关系。)

一旦子集大小大于环境集大小,就没有子集,因此递归的分支停止。

答案 4 :(得分:0)

生成N位的所有二进制文件。 检查每个是否有K个零和K个。 ?。 利润。

答案 5 :(得分:0)

伪代码:

loop for every position starting at left, pos=position:
 loop for every position starting at pos+1 -> pos2;
   set 1 at pos and pos2;

答案 6 :(得分:0)

Binomial Coefficient将为您提供解决方案的总数。 (参见“N选择K”)。

使用Hamming Weight计算位数。

int main()
{
    int k = 2;
    for(int i = 0;  i < 16; i++)
       if(BitCount(i) == k)
          cout << i << endl;
}

// Got this function from an SO question (see below)
int BitCount(int i)
{
    i = i - ((i >> 1) & 0x55555555);
    i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
    return ((i + (i >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}

参考:How to count the number of set bits in a 32-bit integer?

答案 7 :(得分:0)

这是一个值得一去的地方。不过,我没有编译器来测试。

size_t n = 4;
size_t k = 2;

std::vector<bool> bits;

for (size_t i = 0; i < n; i++)
  bits.push_back(i < k ? true : false);

std::sort(bits.begin(), bits.end());

do {
  for (size_t i = 0; i < n; i++)
    cout << ( bits[i] ? '1' : '0' );
  cout << endl;
while(std::next_permutation(bits.begin(), bits.end());

答案 8 :(得分:0)

我认为你已经有了算法:)

首先在左侧布置K的1个,用0的

填充其余部分

向右移动最右边的1 N-K-1次,用0替换先前的位置并每次捕获结果

继续移动1,直到他们全部在右侧

进行。

答案 9 :(得分:0)

递归将是一个很好的解决方案,因为你以某种方式记忆结果或大n&amp; k,当n = 0或n0(只有n> = k将是合法状态)时,程序可能会打击并且你不打印(并进一步递归)。

答案 10 :(得分:-1)

这个问题并不罕见,而且可能难以实现,因此您会很高兴地发现大多数语言都有某种开源解决方案(或DK的一部分)来解决它。

答案 11 :(得分:-2)

每个位只能有2种可能性,所以只需将N提升到2即可。

  1. 1位,可以有两种组合,
  2. 2位,可以有4种组合。
  3. 3位,可以有9种组合
  4. 4位,可以有16种组合