任何消耗少于O(位长)时间的解决方案都是受欢迎的。我需要处理大约1亿个大整数。
answer = [0 for i in xrange(100)]
def pluginBits(val):
global answer
for j in xrange(len(answer)):
if val <= 0:
break
answer[j] += (val & 1)
val >>= 1
答案 0 :(得分:0)
更快速的方法是使用'{:b}'.format(someval)
将整数转换为'1'
s和'0'
s的字符串。 Python仍然需要执行类似的工作来执行此转换,但是在解释器内部的C层执行此操作会对较大的值产生显着较少的开销。
要转换为整数1和0的实际list
,您可以执行以下操作:
# Done once at top level to make translation table:
import string
bitstr_to_intval = string.maketrans(b'01', b'\x00\x01')
# Done for each value to convert:
bits = bytearray('{:b}'.format(origint).translate(bitstr_to_intval))
由于bytearray
是range(256)
中可变的值序列,它迭代实际的int
值,因此您无需转换为list
;它应该可以在list
使用的99%的地方使用,使用更少的内存并且运行得更快。
这会生成与代码生成顺序相反的值(也就是说,bits[-1]
此处与answer[0]
相同,bits[-2]
是您的answer[1]
等等,并且它是未填充的,但由于你是对位进行求和,所以不需要填充,并且反转结果是一个简单的反转切片(在末尾添加[::-1]
)。通过使answer
成为numpy
数组(允许在C层进行大量元素添加)并将其放入,可以使每个输入的位总和更多更快一起得到:
import string
bitstr_to_intval = string.maketrans(b'01', b'\x00\x01')
answer = numpy.zeros(100, numpy.uint64)
def pluginBits(val):
bits = bytearray('{:b}'.format(val).translate(bitstr_to_intval))[::-1]
answer[:len(bits)] += bits
在本地测试中,pluginBits
的这个定义需要不到七分之一的时间来对每个位置的10,000个随机输入整数的每个位进行求和,得到相同的结果。