循环遍历最多k位ON的整数的最佳方法是什么?

时间:2012-05-05 02:15:52

标签: algorithm

我需要遍历所有n位整数,其最多k位为ON(位1),其中0 <1。 n <= 32且0 <= k <= n。例如,如果n = 4且k = 2,那么这些数字是(二进制数字):0000,0001,0010,0100,1000,0011,0101,10110,1001,1010,1100。这些数字的顺序是循环并不重要,但每次只访问一次。

目前我正在使用这种简单的算法:

for x = 0 to (2^n - 1)
    count number of bits 1 in x
    if count <= k
        do something with x
    end if
end for

我认为这种算法效率低下,因为它必须遍历过多的数字。例如,如果n = 32且k = 2,那么它必须循环通过2 ^ 32个数字才能找到529个数字(其中&lt; = 2位1)。

我的问题是:有没有更有效的算法来做到这一点?

5 个答案:

答案 0 :(得分:3)

您需要制作自己的按位计数算法来递增循环计数器。基本上,为了计算序列中的下一个数,如果少于k'1'位,则正常递增,如果有k'1'位,则在最低有效'1'之后假装'0'位存在并正常增加。

另一种说法是,使用标准计数器,您将最低有效位加1并进位。在你的情况下,如果有k个'1',你将把1加到最低的'1'位。

例如,如果k为2并且您1010忽略了上一个0并增加101,那么您获得110然后添加0 } 1100

这是用于递增数字的伪代码:

Count 1 bits in current number
If number of 1's is < k
  number = number + 1
Else
  shift_number = number of 0 bits after least significant 1 bit
  number = number >> shift_number
  number = number + 1
  number = number << shift_number

答案 1 :(得分:1)

回答Bit hack to generate all integers with a given number of 1s并循环[1,k]。这将生成每个最多k位的整数。

答案 2 :(得分:0)

如果必须在4中设置2位,则最低位必须至多为第三位(从0 ... 3开始计数),最高位至少为第二位。

所以你可以用2个循环循环

for lowest in 0 to (n-k)
  for highest in lowest + 1 to 3 
    (0000).setBit (lowest).setBit (highest) 

由于您不想为16位写入16个循环,因此您可以将此想法转换为递归循环。

答案 3 :(得分:0)

组合学

如果您设置了n位长度和r位的整数,则会有nCr个这样的数字。只需使用组合生成器并根据需要迭代组合。

答案 4 :(得分:-1)

你可以使用while循环,如下所示。此循环仅在没有位的情况下循环。如果您修改了没有比特,您可以使用休息

countbits = 0
while num > 0
    num = num & (num-1)
    countbits = countbits + 1
end while

例如:
如果64(1000000)它只循环一次,
如果72(1001000)然后2次