在Python中获取零和二进制数的数量

时间:2013-12-11 11:12:31

标签: python math binary

我正在尝试解决二进制拼图,我的策略是用0和1来转换网格,我想确保每行具有相同数量的0和1。

有没有办法计算一个数字有多少1和0而不重复数字?

我目前正在做的是:

def binary(num, length=4):
    return format(num, '#0{}b'.format(length + 2)).replace('0b', '')

n = binary(112, 8)
// '01110000'
and then
n.count('0')
n.count('1')

有没有更有效的计算(或数学方式)这样做?

2 个答案:

答案 0 :(得分:4)

您要找的是数字的Hamming weight。在较低级别的语言中,您可能会使用漂亮的SIMD within a register技巧或库函数来计算它。在Python中,最简单,最有效的方法是将其转换为二进制字符串并计算'1' s:

def ones(num):
    # Note that bin is a built-in
    return bin(num).count('1')

您可以通过从总位数中减去ones(num)来获得零个数。

def zeros(num, length):
    return length - ones(num)

演示:

>>> bin(17)
'0b10001'
>>> # leading 0b doesn't affect the number of 1s
>>> ones(17)
2
>>> zeros(17, length=6)
4

答案 1 :(得分:2)

如果length适中(比如说小于20),您可以使用列表作为查找表。

如果您正在进行大量查找,那么仅生成列表是值得的,但在这种情况下似乎可能会这样。

例如。对于0计数的16位表,请使用此

zeros = [format(n, '016b').count('0') for n in range(1<<16)]
ones = [format(n, '016b').count('1') for n in range(1<<16)]

在此计算机上生成20位仍然需要一秒钟

修改:这似乎稍快一些:

zeros = [20 - bin(n).count('1') for n in range(1<<20)]
ones = [bin(n).count('1') for n in range(1<<20)]