题目要求
写一个宏,可以将整数n的二进制位的奇数位和偶数位交换。
测试用例
输入:n = 7
输出:n = 11
分析:因为7的二进制序列为 000000000000000000000000000000000111,所以将它的奇数位和偶数位交换之后变成000000000000000000000000000000001011,化成十进制为11
解题思路
由于要交换某个数的奇数位和偶数位,所以我们考虑可以将它的奇数位和偶数位先取出来,然后再放到相应的位置。
那么,我们如何取出奇数位和偶数位呢?
以奇数位为例,比如输入的整数为7,二进制序列为000000000000000000000000000000000111,我们想取出它的奇数位,就应该想办法把它的偶数位都变成0,所以可以采用 & 操作符,将对应的偶数位 & 0,奇数位 & 1,
即 & 10101010101010101010101010101010。
同理,要取出它的偶数位,
我们可以 & 01010101010101010101010101010101。
那么,现在我们可以找到他们的奇数位和偶数位,那应该如何放呢?
其实很简单,将奇数位全部放到偶数位的位置上,将偶数位全部放到奇数位的位置上,我们可以用逻辑左移和逻辑右移来实现这个操作。
如果想操作奇数位,就把奇数位按位与之后的结果左移一位,同理,偶数位右移一位,最后把两者相或,就是我们所求的结果。
注意,由于32位的代码过于冗长,所以我们将其转化为十六进制表示
10101010101010101010101010101010转化成十六进制为0x55555555
01010101010101010101010101010101转化为十六进制为0xaaaaaaaa
具体代码如下:
代码实现
// ((n & 0xaaaaaaaa) >> 1) 偶数位逻辑右移
// ((n & 0x55555555) << 1) 奇数位逻辑左移
// 最终两者相或
#define SWAP(n) n = (((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1))
总结
下次,当我们遇到这种有关二进制位的操作时,我们应该联想到 & | ^
这些操作符,以及逻辑左移,逻辑右移相关的操作,从而巧妙地进行求解。
好了,有关二进制数奇偶交换的题目讲解就到这里了,如果您喜欢本期的内容,请帮博主点上一波关注,谢谢大家!