题目:
二进制中1的个数
题目描述:
输入一个整数,输出该数二进制表示中1的个数。
其中负数用补码表示。
注意:这里是统计输入的整数的二进制表示中1的个数。
方法一:使用移位运算符
//该方法运行时间比较长
//普通方法,使用移位运算符(带符号右移:>>,遇到负数时,由于高位是1,右移,高位补1;无符号右移:>>>,右移时,负数高位补0)
public static int NumberOf2(int n){
int count = 0;
while(n != 0){
if((n&1) == 1){
count++;
n >>>=1;
}
}
return count;
}
方法二:快速法
这种方法速度比较快,其也能算次数与输入n的大小无关,只与n中1的个数有关。如果n的二进制表示中有k个1,那么这个方法只需要循环k次即可。其原理是不断清除n的二进制表示中最右边的1,同时累加计数器,直至n为0。
//运行时间是15ms,占用内存15440k
public static int NumberOf1(int n){
int countBinary = 0;
while(n!=0){
n = n & (n-1); //通过将数字减1并按位与,清除数字的中的1,每次清除数字中的一位1
countBinary ++; //统计该数的二进制表示中的1的个数
}
return countBinary;
}
注:为什么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)。
方法三:
对于这个方法,我只想说一个字“屌”,哈哈哈。
调用JDK中的API方法
//调用JDK api
public static int NumberOf3(int n){
return Integer.toBinaryString(n).replaceAll("0", "").length();
}