LeetCode 之 Reverse Bits

第一种乘除法:

 1 uint32_t reverseBits(uint32_t n) {
 2     int i=32;
 3     int num = 0;
 4     while(i--)
 5     {
 6         if(n%2)
 7             num = num*2 + 1;
 8         else num = num*2;
 9         n = n>>1;
10     }
11     return num;
12 }

显然乘除法效率不高,指令执行周期太长。

第二种简单位运算:

1 uint32_t reverseBits(uint32_t n) {
2     int i;
3     unsigned int num = 0;
4     for(i=0; i<32; i++)
5     {
6         num |= ((n>>i)&1)<<(31-i);
7     }
8     return num;
9 }

第三种分治法,类似于归并排序,可以先每两位调换一次,再每四位调换一次,再每八位调换一次。

1 uint32_t reverseBits(uint32_t n) {
2     n = ((n & 0x55555555) << 1) | ((n >> 1) & 0x55555555);
3     n = ((n & 0x33333333) << 2) | ((n >> 2) & 0x33333333);
4     n = ((n & 0x0f0f0f0f) << 4) | ((n >> 4) & 0x0f0f0f0f);
5     n = ((n & 0x00ff00ff) << 8) | ((n >> 8) & 0x00ff00ff);
6     n = ((n & 0x0000ffff) << 16) | ((n >> 16) & 0x0000ffff);
7     return n;
8 }

具体例子比如:简单点,对于4bit的n=1110来说,(n&0x5)<<1就相当于先取出0100,再移位成1000,第三位的‘1’和第1位的‘0’就被移到了第四位和第二位;类似的先将n>>1,移一位是为了将第4位和第2位分别移到第3位和第1位去,再与0x5相与即可得到移位之后的0101,总的结果相或,得到每两位交换之后的结果1101。再类似进行下去。

posted @ 2015-03-26 15:33  Sprink  阅读(168)  评论(0编辑  收藏  举报