Quetions:
Reverse bits of a given 32 bits unsigned integer.
For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).
Follow up:
If this function is called many times, how would you optimize it?
Related problem: Reverse Integer
题目:
反转一个32位无符号整数的二进制位.
最为直观的得到数的二进制形式,然后直接翻转即可。下面上代码:
int reverseBits(int n) {
char s[32];
int res = 0;
itoa(n, s, 2);
for(int i=0; i<32; i++)
{
if(s[i] == '1')
res += (int)pow(2, 32-i);
}
return res;
}
把里面的int换成uint32_t即可。但是题目有一个follow up说这个函数如果经常被调用的话那么如何优化是的效率更高。上面的代码虽然处理单个问题效率不低,但是调用一次需要做很多的计算,pow()函数那里。之后讨论区想到一个更为优化实用的算法。
一般这种经常调用的情况,为了考虑时间成本,都采取空间换时间的方式。考虑4位二进制,有:
0000 — 0000 0-0
0001 — 1000 1-8
0010 — 0100 2-4
…
1111 — 1111 15-15
我们可以开辟一个这样的表用来存储4位二进制的反转形式,那么32位的数8次循环就可以得到想要的结果。当然这中间还要涉及到移位操作。具体的看代码:
char tb[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
uint32_t reverseBits(uint32_t n)
{
uint32_t res;
uint32_t mask = 0XF; //取n低4位的mask
uint32_t temp;
for(int i=0; i<8; i++)
{
res = res << 4;
temp = n & mask; //取得n的低4位
res = res | tb[temp]; //得低4位的反转码,然后和res异或(等于赋给res的低4位)
n = n >> 4;
}
return res;
}
上面的代码比之前的代码效率更高,因为每次调用不会产生很多的CPU计算(pow函数很耗时间),而且上面的代码还可以继续优化,就是可以以8位为一个单位进行取表,这样表的大小就变成了char tb[256],如果再优化以16位为一个单位取表,那么就是一个char tb[65536]的数组(此时不太方便)。