翻转python中的位

时间:2010-08-20 14:50:49

标签: python algorithm

给定一个整数n,我想切换该数字的二进制表示中的所有位,从低到高。 为此,我执行以下操作[bit_string是一个包含1和0的字符串,是n的二进制表示]

for i in range(lower,upper+1):
   n ^= (1 << len(bit_string)-1-i) #Toggle the ith bit

然后,我还需要确定给定一个范围,比如从低到高,设置了多少位。我的代码如下:

number_of_ones = 0
for i in range(lower,upper+1):
    if(n & (1 << len(bit_string)-1-i)): #Check the ith bit
      number_of_ones+=1

但是,如果n非常大,我认为这些算法会很慢。有没有办法让这两项操作更快/更有效?

谢谢

4 个答案:

答案 0 :(得分:12)

对于“翻转”,您可以创建一个位图(包含所有感兴趣的位置)和一个独占 - 或者:

n ^= ((1<<upper)-1)&~((1<<lower)-1)

对于位计数,一旦你隔离(n&amp; mask)与上述RHS相同的“掩码”,将其切成例如8位切片并查找查找表中的8位计数(只需要一个简单的listarray.array来预先准备)是最快的方法。

gmpy有一些有用且快速的位操作和计数操作,尤其是如果你处理的是非常长的字符串(超过一个机器字的价值,那么在Python中它们将是long个实例),比Python的原生产品更快。

答案 1 :(得分:1)

def bitflip(n,range):
    bitfliplen = range[1]-range[0]
    return n ^ ((2**bitfliplen-1) << (range[0]))

运行:

>>> a = 47727124L
>>> b = bitflip(a,(5,10))
>>> print "a: {0:b}\nb: {1:b}".format(a,b)
a: 10110110000100001000010100
b: 10110110000100000111110100
>>>

答案 2 :(得分:1)

对于位计数,一旦你屏蔽了你感兴趣的范围,请参阅实现Brian Kernighan方案的python BitManipulation wiki page上的bitCount()例程:

def bitCount(int_type):
    count = 0
    while(int_type):
        int_type &= int_type - 1
        count += 1
    return(count)

答案 3 :(得分:0)

我不知道python所以我只是从一个纯粹的数学观点来看这个......

在我看来,对于第一部分,更有效的方法可能是构造一个首先要作为整数切换的位的掩码。为了让生活变得简单,我将假设你从最低有效位为0计算你的下限和上限,最重要的是31(或者你的情况下适合int的长度)。

如果希望翻转比特n到m(m> n),则数字2 ^(m + 1)-2 ^ n的二进制表示将设置这些比特。然后进行异或,你可以一次性完成所有交换。计算机应该一次性完成这些操作,而不是每位交换一次。

至于计数,我不确定。有一些方法可以计算一个数字中的设置位数。我不确定你是否可以获得效率提升,使用上面的位掩码和一个AND来计算你不关心计算nad的所有位然后使用这些算法,或者你最好修改它们为你工作。我不知道他们是如何工作的。 :)