我试过谷歌搜索,但找不到任何可以理解的东西@。@ ... 有人可以用非专业人的术语解释这段代码中发生的事情吗?
这是“破解编码面试”一书中的一个问题。
“编写程序以尽可能少的指令交换整数中的奇数和偶数位(例如,交换位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) );
答案 0 :(得分:4)
让我们打破这一点。
return ( ((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1) );
首先,我们会看(x & 0xaaaaaaaa)
。如果您将0xaaaaaaaa
分解为比特级别,则最终得到1010 1010 1010 1010 1010 1010 1010 1010
(a
,二进制为1010
)。所以(x & 0xaaaaaaaa)
说,只返回1
中每个偶数位x
。这称为位掩码。然后,你将它右移一个位置 - 这就是你如何使偶数数字切换位置(所以现在第二位占据第一位的位置,第四位占据第三位等)。
您使用(x & 0x55555555)
执行相同操作 - 如果将其细分为位级别,则最终得到0101 0101 0101 0101 0101 0101 0101 0101
(如5
,二进制,{{1} })。这会掩盖0101
中所有偶数位,并为您提供所有奇数位。然后,将所有位移到1.最后,使用x
(or
)运算符组合两个位序列,这就是你的答案。
实施例:
我们将其转换为二进制文件并获取|
。现在,我们执行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
,正如您所见,这是解决方案!
答案 1 :(得分:4)
转换为二进制,
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
答案 2 :(得分:1)
我们知道0xaa和0x55是十六进制表示形式。 此外,十六进制中的每个字符都使用4位表示
so,0xaa等于1010 1010(因为a = 1010二进制) 并且0x55等于0101 0101(因为5 = 0101,二进制)
将任何数字与其相加会返回给我们 数字,因此在解决诸如交换奇数之类的问题时很有用 甚至是数字。