无符号整数翻转函数实现reverse_bits(unsigned int value)

题目:

Reverse Bits

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?

PS:leetcode

一般的解决方案就是从左至右判断每一位,把获得的结果加在结果上,编码如下,

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        uint32_t bit = 0;
        uint32_t result = 0;
        uint32_t tmp = n;
        while(bit<32)
        {
            if((tmp>>bit) & 1 == 1)
                result = result + (1<<(31-bit));
    
            bit ++;
        }
    
        return result;
    }
};

这种方式简单易懂,但是效率不高,时间复杂度为O(n),n为数据类型的位数。

咱们换个角度想想,既然我们给定的数可以通过移动获得每一位的数字,那么我们也可以移动结果来填充每一步的值。

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        uint32_t  answer;
        uint32_t int i;
    
        answer = 0;
    
        /*把一个unsigned int 数字1一直左移,直到它变成全0的时候,也就得到了该机器内unsigned int的长度*/
        for (i = 1; i != 0; i <<= 1)
        {
            answer <<= 1;
            if (value & 1) { answer |= 1; }
            value >>= 1;
        }
    
        return answer;
    }
};

这种方案将结果按照数据类型的位数进行移动,每次移动时判断value的最后一位是否为1,如果为1,那么在结果的最后一位添加1,如果不是,继续移位。
这种方案效率会高很多,因为我们知道对于C++编译器来讲,位操作肯定会比加法操作效率高得多。

试想一下,我们还有没有更好的方案呢,答案当时是肯定的。

http://graphics.stanford.edu/~seander/bithacks.html

在斯坦福的这篇文章里面介绍了众多有关位操作的奇思妙想,有些方法的确让人称赞,其中对于位翻转有这样的一种方法,将数字的位按照整块整块的翻转,例如32位分成两块16位的数字,16位分成两个8位进行翻转,这样以此类推知道只有一位。

对于一个8位数字abcdefgh来讲,处理的过程如下

abcdefgh -> efghabcd -> ghefcdab -> hgfedcba

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        n = (n >> 16) | (n << 16);
        n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8);
        n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4);
        n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2);
        n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1);
        return n;
    }
};

这种方法的效率为O(log sizeof(int))。

原文地址:https://www.cnblogs.com/lvxz/p/4332082.html