请解释Kernighan的位计数算法背后的逻辑

时间:2012-09-12 07:18:20

标签: java algorithm bit-manipulation bit

在阅读 Bits counting algorithm (Brian Kernighan) in an integer time complexity之后,这个问题直接出现。有问题的Java代码是

int count_set_bits(int n) {
  int count = 0;
    while(n != 0) {
      n &= (n-1);
      count++;
    }
 }

我想了解n &= (n-1)在这里取得的成就?我在另一个漂亮的算法中看到了类似的构造,用于检测数字是否是2的幂,如:

if(n & (n-1) == 0) {
    System.out.println("The number is a power of 2");
}

2 个答案:

答案 0 :(得分:31)

逐步调试调试器中的代码帮助了我。

如果你从

开始
n = 1010101 & n-1=1010100 => 1010100
n = 1010100 & n-1=1010011 => 1010000
n = 1010000 & n-1=1001111 => 1000000
n = 1000000 & n-1=0111111 => 0000000

所以这次迭代4次。每次迭代都会以这样的方式递减值,即设置为1的最低有效位消失。

一个减少翻转最低位,每个位翻到第一个。例如如果你有1000 .... 0000 -1 = 0111 .... 1111无论有多少位都要翻转它停在那里留下任何其他位未设置。当您和n设置最低位且仅最低位变为0

答案 1 :(得分:2)

Subtraction of 1 from a number toggles all the bits (from right to left) till the rightmost set bit(including the righmost set bit). So if we subtract a number by 1 and do bitwise & with itself (n & (n-1)), we unset the righmost set bit. In this way we can unset 1s one by one from right to left in loop.

The number of times the loop iterates is equal to the number of set bits.

Source : Brian Kernighan's Algorithm