给定一个整数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非常大,我认为这些算法会很慢。有没有办法让这两项操作更快/更有效?
谢谢
答案 0 :(得分:12)
对于“翻转”,您可以创建一个位图(包含所有感兴趣的位置)和一个独占 - 或者:
n ^= ((1<<upper)-1)&~((1<<lower)-1)
对于位计数,一旦你隔离(n&amp; mask)与上述RHS相同的“掩码”,将其切成例如8位切片并查找查找表中的8位计数(只需要一个简单的list
或array.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的所有位然后使用这些算法,或者你最好修改它们为你工作。我不知道他们是如何工作的。 :)