Python 如何反转数字的交替位

Python 如何反转数字的交替位,python,bit-manipulation,Python,Bit Manipulation,问题是如何从LSB开始反转数字的交替位。目前我正在做的是首先做一个 count = -1 while n: n >>= 1 count += 1 要首先找到最左边设置位的位置,然后运行循环以反转每个备用位,请执行以下操作: i = 0 while i <= count: num ^= 1<<i i += 2 i=0 虽然我认为这可能有效: 具有交替掩码的按位异或应每隔一位反转一次 如果要反转“0011”中的交替位,下表显示了结果: i | m |

问题是如何从
LSB
开始反转数字的交替位。目前我正在做的是首先做一个

count = -1
while n:
   n >>= 1
   count += 1
要首先找到最左边设置位的位置,然后运行循环以反转每个备用位,请执行以下操作:

i = 0
while i <= count:
 num ^= 1<<i
 i += 2
i=0

虽然我认为这可能有效:

具有交替掩码的按位异或应每隔一位反转一次

如果要反转“0011”中的交替位,下表显示了结果:

i | m | i XOR m
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0

在python中,XOR是通过
i^m
实现的。当然,您也必须确定掩码的文字值,这取决于您的
i
编号的大小。

根据trideceth12给出的答案展开-下面是一条计算并应用掩码的一行代码:

n ^ sum(2**i for i in range(0, len(bin(n))-2, 2))
。。。假设您确实想从LSB开始,也就是说

或者,如果从最重要的设置位开始:

n ^ sum(2**i for i in range(len(bin(n))-3, -1, -2))

以前的一行解决方案

n ^ sum(2**i for i in range(0, len(bin(n))-2, 2))
是一个O(lg n)解决方案,其中n是输入编号。下面所示的渐近快得多的解在时间O(lg(lg n))中运行,也就是说,在时间上与输入数字中的位数的对数成正比。注意,如图所示的二进制搜索在测试中工作正常,但可能可以改进


编辑:表达式
-1这将适用于任何长度的正整数:

def invert_alt_bits(n):
    m = 1
    while True:
        n ^= m
        m <<= 2
        if m > n: break
    return n
def反转替换位(n):
m=1
尽管如此:
n^=m

m我假设您感兴趣的是首先查找msb,而不是lsb,在big-endian体系结构中(我假设您有),您熟悉最左边的lsb位出于兴趣,您对该算法的应用程序有什么想法?没有。这是一个面试问题..:PIs您的答案是“我会征求关于堆栈溢出的建议吗?”:在找到msb后,pXOR是正确的解决方案,因为0^1->1适用于任何长度数字,只要掩码长度相同,我相信@ZeroPiraeus answer会根据输入的长度计算出适当的长度掩码。答案中的8位掩码只是一个例子。看起来很有希望。请您详细说明一下
-1@Cupidvogel,我添加了一个段落re,该段落还添加了注释re我对“备用位”的解释,即从MSB正下方的位开始。要始终切换位0,2,4。。。如果L&1:k=k,则删除,而不是有时的1,3,5…。OP问题的第一行说“问题是如何从LSB开始反转一个数字的交替位”,这听起来不像是根据你在笔记中所说的第一部分所做的。@martineau,谢谢你指出这一点。是,如果L&1:k=Kforn=0b11011,则
会生成不正确的0b01110。(应该是0b10001。)@jwpat7:I
assert 0b11011^0b10101==invert_alt_位(0b11011)
我同意0b11011^0b10101==invert_alt_位(0b11011)。这个等式证明了invert_alt_bits()对所述问题的回答是错误的。@jwpat7:我想我们对“所述问题”的解释是不同的。在问题中运行代码与您的解释一致;ie问题代码也给出了0b01110,就像Zero Piraeus的第一条一号班轮一样。
0b11011 has 5 bits.
0b10001 fin

0b11110100001001 has 14 bits.
0b10100001011100 fin

0b110100111001001110000011001001100110111010000111 has 48 bits.
0b100001101100011011010110011100110011101111010010 fin

0b10011110100000000111000001101101000001011000100011000010010000111010101 has 71 bits.
0b11001011110101010010010100111000010100001101110110010111000101101111111 fin
def invert_alt_bits(n):
    m = 1
    while True:
        n ^= m
        m <<= 2
        if m > n: break
    return n