题目描述:
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
解题思路
主要介绍3种方法:
- Java API
- &运算符
1 . Java API
Integer.toBinaryString(10);//得到10的二进制表示的字符串表示 "1010"
Integer.toBinaryString(-10);//得到是补码的形式表示"11111111111111111111111111110110" (4个字节)
//判1的个数,可以遍历判断,也可以subString(x,x+1)来判断第x位的。
//遍历判断
for(int i=0; i<s.length(); i++){
if(s.charAt(i)=='1')
count++;
}
//subString判断
for(int x=0; x<s.length(); x++){
if(s.subString(x,x+1)=='1')
count++;
}
具体Java代码实现在下面模块。
2 . & 运算
先介绍 & 运算符
看个例子:
10 & 1 => 二进制 1010 & 0001 = 0000 =>十进制 0
10 & 2 => 二进制 1010 & 0010 = 0010 =>十进制 2
10 & 4 => 二进制 1010 & 0100 = 0000 =>十进制 0
10 & 8 => 二进制 1010 & 1000 = 1000 =>十进制 8
我们可以观察到 &运算符 就是 左右两个数的二进制表示之后再对相同的位进行比较,比较规则是与规则,有0为0,全1为1。
其实,在上面我们不知不觉就把10的二进制表示1的个数求出来了,我们观察到 &运算结果 不为0 的相应位都是1,例子中1的个数为2 (10 的二进制 1010 , 1的个数就是2)。
当然,这种做法,对于负数一样是有效的,由于 &运算符 会自动将负数用补码进行表示,所以我们完全不用担心!
那木,具体怎么实现上面的方法呢?
观察上面例子中,&运算符右边的数的变化,是不是1一直在不断的左移一位啊!
其实我们完全可以等效的来表示:
10 & 1 => 二进制 1010 & 0001 = 0000
10>>>1 & 1 => 二进制 0101 & 0001 = 0001
10>>>2 & 1 => 二进制 0010 & 0001 = 0000
10>>>3 & 1 => 二进制 0001 & 0001 = 0001
先解释下 >>>运算符,其表示无符号右移相应位,就是二进制右移相应位数之后,左边全部补0。
上面的等价是相对的思想,让&运算符右边的不动,左边的动,达到同样的效果,虽然计算结果不同,但是是否为0完全能够判断出来!也就是不是1完全能够判断出来!
具体实现如下:
int num = 10;
int count = 0;
do{
if((num & 1) != 0)
count++;
num>>>=1;
}while(num != 0);
以上2种方法的完整Java代码:
Java API
public class Solution {
public int NumberOf1(int n) {
int count = 0;
String s = Integer.toBinaryString(n);
for(int i=0; i<s.length(); i++){
if(s.charAt(i)=='1')
count++;
}
return count;
}
}
& 运算符
public class Solution {
public int NumberOf1(int n) {
int count = 0;
do{
if((n & 1) != 0)
count++;
n >>>= 1;
}while(n != 0);
return count;
}
}
End