我试着用谷歌搜索,但找不到任何可以理解的东西@ ...有人能用通俗易懂的语言解释一下这段代码里发生了什么吗?
这是“破解编码面试”一书中的一个问题。
编写一个程序,用尽可能少的指令交换整数中的奇数位和偶数位(例如,位0和位1交换,位2和3交换,依此类推)。
我这样做的方式不涉及位操作,因为我不知道如何%\ ...
def swap(n):
b = bin(n)[2:]
print(b)
if len(b)%2 != 0:
c = True
b = b[0] + b
pairs = wrap(b, 2)
pairs = [i[::-1] for i in pairs]
ans = ''.join(pairs)
if c: ans = ans[1:]
print(ans)
但现在我看着他们的答案,我真的不明白...(它不在Python中也无济于事):
int swapOddEvenBits(int x) {
return ( ((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1) );
发布于 2017-05-12 03:28:16
让我们来分析一下。
return ( ((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1) );
首先,我们来看看(x & 0xaaaaaaaa)
。如果您将0xaaaaaaaa
分解到位级别,您最终会得到1010 1010 1010 1010 1010 1010 1010 1010
(因为a
在二进制中是1010
)。所以(x & 0xaaaaaaaa)
的意思是,在x
中只返回每个偶数放置的1
。这称为位掩码。然后,将其右移一位-这就是如何使偶数交换位置(所以现在第二位占据第一位的位置,第四位占据第三位,依此类推)。
你也可以用(x & 0x55555555)
做同样的事情--如果你把它分解到位级别,你最终会得到0101 0101 0101 0101 0101 0101 0101 0101
(因为5
在二进制中就是0101
)。这将屏蔽x
中的所有偶数位,并给出所有奇数位。然后,将所有位左移1。最后,使用or
(|
)运算符组合两个位序列,这就是您的答案。
例如:让我们取2456086205。我们将其转换为二进制文件,并得到1001 0010 0110 0100 1110 0110 1011 1101
。现在,我们执行(x & 0xaaaaaaaa)
,并得到
1001 0010 0110 0100 1110 0110 1011 1101 & 1010 1010 1010 1010 1010 1010 1010 1010
,
这等于1000 0010 0010 0000 1010 0010 1010 1000
。将这个向右移动,你就会得到0100 0001 0001 0000 0101 0001 0101 0100
。
现在,执行(x & 0x55555555)
,并获取
1001 0010 0110 0100 1110 0110 1011 1101 & 0101 0101 0101 0101 0101 0101 0101 0101
,
这等于0001 0000 0100 0100 0100 0100 0001 0101
。将这个向左移动,你就会得到0010 0000 1000 1000 1000 1000 0010 1010
。
最后,我们执行0100 0001 0001 0000 0101 0001 0101 0100 | 0010 0000 1000 1000 1000 1000 0010 1010
。然后我们得到0110 0001 1001 1000 1101 1001 0111 1110
,正如你所看到的,它就是解决方案!
发布于 2017-05-12 03:32:21
转换为二进制,
0xaaaaaaaa == 0b10101010101010101010101010101010
0x55555555 == 0b01010101010101010101010101010101
这些数字在交替的位置设置了0和1,所以当你用这些数字中的一个&
一个数字时,它会每隔一秒挑选一位。
如果使用整数执行swapOddEvenBits过程,假设是0b01111100111101001111110000110010
,我们会得到
0xaaaaaaaa & 0b01111100111101001111110000110010 selects the following bits:
0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1 # unselected bits are 0
0x55555555 & 0b01111100111101001111110000110010 selects the following bits:
1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0
0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1 gets shifted right:
0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1
and
1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0 gets shifted left:
1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0
and we | the results back together:
0 1 1 0 1 1 0 0 1 1 1 0 0 1 0 1
1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 0
-------------------------------
10111100111110001111110000110001
发布于 2019-08-22 19:06:34
我们知道0xaa和0x55是十六进制表示。此外,十六进制中的每个字符都使用4位表示
因此,0xaa等同于1010 1010 (因为,a= 1010二进制),0x55等同于0101 0101 (因为,5= 0101二进制)
对任何数字进行and运算都会返回该数字的其他位,因此在解决诸如交换奇数和偶数这样的问题时很有用。
https://stackoverflow.com/questions/43923906
复制相似问题