如何生成所有长度为 n 且设置了 k 位的二进制模式? (使用递归)

Posted

技术标签:

【中文标题】如何生成所有长度为 n 且设置了 k 位的二进制模式? (使用递归)【英文标题】:How to generate all binary patterns of length n with k bits set ? (using recursion) 【发布时间】:2018-02-12 06:18:26 【问题描述】:

我想编写一个函数来生成所有长度为 n 且设置了 k 位的二进制模式。这些模式可以存储在二维数组中。看起来我需要递归来实现这一点。任何代码或伪代码都会有所帮助。

示例:如果 n=5 和 k=3 生成:

111001101011001101101010110011 01110 01101 00011 00111

我发现了类似的帖子:Generate all binary strings of length n with k bits set,但建议的解决方案计算所有 2^k 组合。

【问题讨论】:

这肯定是和***.com/questions/46023719/… 相同的问题,只是几个小时前问的? (递归请求除外,这对于高效实现来说绝对不是必需的。) 此外,您链接的问题的已接受答案 not 会生成所有 2^k 组合。你试过了吗? @rici 对我链接到的问题的接受答案,将数字作为输入:unsigned int v; // 当前位的排列 unsigned int w; // 下一个位排列 @David,那个参数 v 只是前面的排列。用第一个数字调用它很容易,然后用函数返回的前一个结果继续调用它。该问题还有其他几个有用的答案。这是一个骗局。 Generate all binary strings of length n with k bits set的可能重复 【参考方案1】:
For i = 0...(1<<n)-1
    If countsetbits(i) == k
        Store into collection

countsetbits(i) 在哪里:

j = i
For b = 0...n
    If j == 0
        Return b
    j = j And (j - 1)

以你的例子,其中

n = 5, k = 3

你得到

i     b j=0? j     And(j-1)          Return b   Main loop
0...6                                           less than k
7     0 No   111b  And 110b = 110b  
      1 No   110b  And 101b = 100b  
      2 No   100b  And 011b = 000b  
      3 Yes                          3          k, hence store into collection
8     0 No   1000b And 0111b = 0000b
      1 Yes                          1          less than k
9     0 No   1001b And 1000b = 1000b
      1 No   1000b And 0111b = 0000b
      2 Yes                          2          less than k
10    0 No   1010b And 1001b = 1000b
      1 No   1000b And 0111b = 0000b
      2 Yes                          2          less than k
11    0 No   1011b And 1010b = 1010b
      1 No   1010b And 1001b = 1000b
      2 No   1000b And 0111b = 0000b
      3 Yes                          3          k, hence store into collection
...
31    ...                            5          greater than k

【讨论】:

谢谢。但这不是运行 2^n 次迭代吗?这是我要避免的。【参考方案2】:

这个任务的递归实现很简单(Delphi和伪代码)

  procedure GenKBits(Value, Position, N, K: Integer);
  begin
    if K = 0 then
      Output Value in binary
    else
      if (Position < N) then begin
        GenKBits(Value or (1 shl Position), Position + 1, N, K - 1); //set bit
        GenKBits(Value, Position + 1, N, K);             //use zero bit
      end;
  end;

call  GenKBits(0, 0, 4, 2) gives

0011
0101
1001
0110
1010
1100

【讨论】:

以上是关于如何生成所有长度为 n 且设置了 k 位的二进制模式? (使用递归)的主要内容,如果未能解决你的问题,请参考以下文章

多项式如何转换二进制

大水题(water)

生成一个二进制数列表,其中 n 位设置为 1

如何并行计算 k 个集合位的所有组合?

关于bitset

位操作将最左侧的设置位转换为右侧的交替位?