我需要遍历所有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)。
我的问题是:有没有更有效的算法来做到这一点?
答案 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次