java1的个数_二进制中1的个数(java)

题目:

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

分析:

首先,复习下java的int型表示范围:

java的int型由4个字节组成,即32位。 减去最高位符号位,共有31位,故表示的范围是 正负2^32(10位十进制数)。

再“预习”下负数的补码表示方法。

(1),java使用2的补码这种方式来编码负数。即,除过符号位,先对每一位取反,再加1;

例如: -42就是通过取反42中所有的位00101010来表示,得到11010101,然后再加1,得到11010110,即-42 。要解码一个负数,首先取反其所有的位,然后加1。例如-42,或11010110取反后为00101001,或41,然后加1,这样就得到了42。

(2),其次,比较特殊的几个数字:+0, -0, -1;

假定有一个byte型值,0用00000000代表。在补码表示中,只是取反所有的位,即生成11111111,它代表负0。而在整数数学中,负0是无效的。所以可以使用2的补码来表示负数。当使用2的补码时,对补码加1,产生了100000000。但这时1位太靠左不能返回到byte类型的值。因此我们规定,-0和0的表示方法是一样的,-1的解码为11111111。

最后,来学习下此题的解法,上述只是基础知识点,此题使用位运算。

(1)解法一: 整数n每次无符号右移一位,检查最右边的bit是否为1来进行统计;代码如下:

public int count1(int n){

int res = 0;

while(n != 0){

res += n&1;

n>>>=1; //等效于: n += 1;

}

return res;

}

此方法需要经过32 次循环比较;稍微多;

(2)解法二:每次进行n&(n-1)的操作,例如: n=01000100, n-1= 01000011;

n&(n-1) = 01000000; 令n=n&(n-1), 继续此过程,只需要比较两次即可。代码如下:

public int count1(int n){

int res = 0;

while(n != 0){

n &= (n-1);

res++;

}

return res;

}

(3)解法三: 和解法二次数一样。通过移除n最右边1的操作:

n -= n & (~n + 1),

来统计1的个数。

代码实现如下:

public int count3(int n){

int res = 0;

while(n != 0){

n -= n & (~n + 1);

res++;

}

return res;

}

注:此题属于位运算的题目,牢记。

部分参考:https://blog..net/asd1415926/article/details/15500593

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值