題目
計算在一個 32 位的整數的二進制表式中有多少個 1.
樣例
給定32(100000),返回1
給定5(101),返回2
給定1023(111111111),返回9
分析
方法一 普通法
最容易想到的方法,通過移位加計數,一個個計算統計1的個數
public int countOnes1(int num){
int count = 0;
while(num!=0){
if(num%2==1)
count++;
num=num/2;
}
return count;
}
改進的普通法
用位操作替代方法一
public int countOnes2(int num){
int count = 0;
while(num!=0){
count +=num&0x01;
num = num>>1;
}
return count;
}
方法三 快速法
這種方法速度比較快,其運算次數與輸入n的大小無關,只與n中1的個數有關。如果n的二進制表示中有k個1,那么這個方法只需要循環k次即可。其原理是不斷清除n的二進制表示中最右邊的1,同時累加計數器,直至n為0
為什么n &= (n – 1)能清除最右邊的1呢?因為從二進制的角度講,n相當于在n - 1的最低位加上1。舉個例子,8(1000)= 7(0111)+ 1(0001),所以8 & 7 = (1000)&(0111)= 0(0000),清除了8最右邊的1(其實就是最高位的1,因為8的二進制中只有一個1)。再比如7(0111)= 6(0110)+ 1(0001),所以7 & 6 = (0111)&(0110)= 6(0110),清除了7的二進制表示中最右邊的1(也就是最低位的1)
public int countOnes3(int num){
int count = 0;
while(num!=0){
num = num & (num-1);
count++;
}
return count;
}