【问题标题】:What is an efficient code for generating n binary digit numbers with k bits set as one?什么是生成 n 个二进制数且 k 位设置为 1 的有效代码?
【发布时间】:2017-09-03 13:07:21
【问题描述】:

是否有任何有效的代码可以生成具有 n 位二进制表示且恰好 r 位设置为 1 的数字?

这也是生成掩码以查找集合的 NcR 组合的好策略吗?

我考虑过生成所有 2^n 个数字并计算它们的位数,但计数位数似乎是 O(nlogn)。

【问题讨论】:

  • HAKMEM 175 描述了查找具有相同位数集的下一个更高整数的方法,请检查相关answer
  • 如果 n 是(小于)机器字的大小,您可以在恒定时间内计算 1 - 但无论如何您都不应该使用这种方法,2^n 要大得多比实际的组合数。

标签: algorithm combinations bitmask


【解决方案1】:

好吧,如果给定一个设置了 K 位的数,我们如何找到设置了 K 位的 下一个最大的数?如果我们反复这样做,我们可以生成所有这些。

生成下一个分解为几个简单的规则:

  1. 更改的最高位必须从 0 变为 1。否则新数字将小于给定数字。
  2. 更改的最高位必须是可能的最低位。否则在当前号码和新号码之间会有其他有效号码。当我们将一个位从0变为1时,我们必须将另一个位从1变为0,并且这个位必须更小,所以我们要从0变为1的高位是最低的0位和1位在较低的位置。
  3. 剩余的低位必须设置为其最小的有效配置。否则,在当前数字和新数字之间将再次存在其他有效数字。低位的最小有效配置是所有 1 位都在最低位置的配置。

事实证明,很少有二进制数学技巧可以轻松实现所有这些规则。这是在python中:

N = 6 # length of numbers to generate
K = 4 # number of bits to be set

cur = (1<<K)-1  #smallest number witk K bits set

while cur < (1<<N):

    print format(cur,'b')

    #when you subtract 1, you turn off the lowest 1 bit
    #and set lower bits to 1, so we can get the samallest 1 bit like this:
    lowbit = cur&~(cur-1)

    #when you add lowbit, you turn it off, along with all the adjacent 1s
    #This is one more than the number we have to move into lower positions
    ones = cur&~(cur+lowbit)

    #cur+lowbit also turns on the first bit after those ones, which
    #is the one we want to turn on, so the only thing left after that
    #is turning on the ones at the lowest positions
    cur = cur+lowbit+(ones/lowbit/2)

您可以在这里试用:https://ideone.com/ieWaUW

如果您想使用位掩码枚举 NcR 组合,那么这是一个很好的方法。例如,如果您希望拥有所选项目的索引数组,那么最好使用不同的过程。您也可以制定上述 3 条规则来增加该数组。

【讨论】:

  • 你能告诉我如何编写 3 个这样的规则来增加该数组吗?
  • 如果你问一个不同的问题,我会的。这个是关于比特的,非常接近于复制。
猜你喜欢
  • 2010-12-23
  • 2022-01-06
  • 2018-02-12
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
  • 2015-06-08
  • 2021-05-29
相关资源
最近更新 更多