有没有有效的方法来增加整数数组中整数的相应设置位置?

时间:2018-02-06 02:17:25

标签: python python-2.7 bit-manipulation

任何消耗少于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

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))

由于bytearrayrange(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个随机输入整数的每个位进行求和,得到相同的结果。