题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
回顾知识点(原码,反码,补码)
数字在计算机中都是二进制来存在,以字节为单位,一个字节是8位,这个题目是int类型就是32位
原码:最高位是符号位,剩下的表示机器数的值
+1:0000 0001
-1:1000 0001
反码:对于整数,反码同原码,对于负数符号位不变,剩下的位取反
+1:0000 0001
-1:1111 1110
补码:对于整数,补码同源,对于负数反码的基础加1
+1:0000 0001
-1:1111 1111
分析题目
首先Interger类中提供了现有方法
Integer.bitCount(n);
要统计二进制数中1的个数,首先想到的思路是让该整数与1进行“与运算”,然后向右移位来得到1的个数,但是负数用补码表示,最高位是1,这样造成死循环
public static int NumberOf1_CanNotUse(int n) {
int count = 0;
while (n != 0) {
if ((n & 1) == 1) {
count++;
}
n = n >> 1;
}
return count;
}
所以换一种思路,让计算的数不要动,让1向左移位,并与该数进行与运算
public int NumberOf1(int n) {
int count=0;
int flag=1;
while(flag!=0){
if((n&flag)!=0){
count++;
}
flag=flag<<1;
}
return count;
最优解:只用整数自己判断,如果n!=0;计算器先加1;然后n=n&(n-1),就“减去”了n中的一个1,一直到减去所有的1,这个时候n==0,循环结束
public int NumberOf1_2(int n) {
int count=0;
while(n!=0){
++count;
n=n&(n-1);
}
return count;
}