Integer.bitCount 的函式解析#
- 要計算整數以二進制的方式表示時,所有 bit 位為 1 的總和。
public static int bitCount(int i){
int count = 0;
while (i > 0) {
if ((i & 1) == 1) // 如果最低位為 1,count就加 1
count++;
i >>= 1; // 向右推進 1 位,等同於 num /= 2;
}
return count;
}
- 時間複雜度為 \(O(n)\),\(n\) 為整數的位數(bit 數)。
- 利用(i - 1) & i 可以消除最低位數的 1 的性質來計算。
public static bitCount(int i){
int count = 0;
while (i > 0){
i = i & (i - 1); // 0b0101_1100 - 1 = 0b0101_1011, 且 0b0101_1100 & 0b0101_1011 = 0b0101_1000;
count++;
}
return count;
}
- 時間複雜度為 \(O(n))\),\(n\) 為位數為 1 的個數。
利用 int 的特性再優化#
- 因為 int 的最大正整數為 2^31,故我們可以兩兩錯位相加來求和
private static int bitCount(int i){
i = (i & 0x55555555) + ((i >>> 1) & 0x55555555); // 0b0101_0101_0101_0101_0101_0101_0101_0101
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); // 0b0011_0011_0011_0011_0011_0011_0011_0011
i = (i & 0x0f0f0f0f) + ((i >>> 4) & 0x0f0f0f0f); // 0b0000_1111_0000_1111_0000_1111_0000_1111
i = (i & 0x00ff00ff) + ((i >>> 8) & 0x00ff00ff); // 0b0000_0000_1111_1111_0000_0000_1111_1111
i = (i & 0x0000ffff) + ((i >>>16) & 0x0000ffff); // 0b0000_0000_0000_0000_1111_1111_1111_1111
return i;
}
Source Code(final)#
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
- 一、三、四、五步不進行消位,在最後再利用 i & 0x3f 消去不必要的位數