二进制中1的个数(剑指Offer 第 11 题)

来源:互联网 发布:淘宝买化妆品可靠吗 编辑:程序博客网 时间:2024/05/21 06:25

题目描述:


输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。


解题思路


主要介绍3种方法:

  1. Java API
  2. &运算符

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 =>十进制 010 & 2 => 二进制 1010 & 0010 = 0010 =>十进制 210 & 4 => 二进制 1010 & 0100 = 0000 =>十进制 010 & 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