Java中的反转位 - O(n)

时间:2016-07-30 05:46:43

标签: java bit-manipulation reverse bits

我正在尝试理解这个在O(n)时间内反转位的代码。我理解时间复杂度,但我无法理解这段代码背后的逻辑。

public static long reverse(long a) {
    long result = 0;
    int i = 31;
    while(a > 0){

        result += (a % 2) * Math.pow(2, i);
        i--;                        
        a = a/2;
    }
    return result;
}

为了保持简单,例如,如果我取12(1100)且只有4位(设置i = 3),我的输出将是3(0011)。我明白了,我也能得出答案。

但有人可以解释这段代码背后的逻辑吗?谢谢!

2 个答案:

答案 0 :(得分:2)

该代码是

  1. 打破了一半可能的位模式(所有负数)和
  2. O(n),而不是O(log n),其中n是a
  3. 中的位数
  4. 非常低效
  5. 令人困惑的写作
  6. 该算法仅适用于正数,并且确实:

    extract the rightmost bit from a
    set the corresponding bit from the left end
    shift a one position to the right
    

    只要a > 0重复。如果a的值具有一些前导零位,那么该算法将比O(n)稍好一些。

    尽管现代编译器能够将a/2转换为a >> 1和{,但

    当掩码和移位的位提取的余数和除法产生的效率低得多。 {1}}到a%2。但是,我不知道它是否会将a & 0x00000001识别为Math.pow(2, i);

答案 1 :(得分:1)

以下是解释

i = 31 //number of bits in integer

以下有两部分

result += (a % 2) * Math.pow(2, i);

(a % 2)计算最后一位。  将任何具有正幂2的函数乘以具有左移位的效果。 (Math.pow(2, i)向左移i次。

因此我们计算单位位置并将其放置在单位位置的第i个位置,即右侧(31 - i),这有效地将位的位置从左向右反转。

最后

i--; //move to next bit
a = a/2; //chop the unit place bit to proceed to next.

就是这样。