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。再类似进行下去。