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

题目描述:


输入一个整数,输出该数二进制表示中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 =>十进制 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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值