整数的二进制表达中有多少个1

【题目】

给定一个32位整数n,可为0,可为正负,返回该整数二进制表达中1的个数。

【思路】

这题和数据是正数还是负数关系不大,因为只要是数据,在计算机中就是以补码表示,计算机会自动转化(不是在考你负数的补码表示是什么,计算机已经帮你做好了),这道题考察的是:二进制表示的一个数据,如何计算出它的1的个数

方法2:

如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。

举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。

【代码】


public static void main(String[] args) {
        int a = 0b1000101111;
        System.out.println(a&1);//1
        System.out.println(countOne(a));//6
        System.out.println(countOne2(a));//6
        System.out.println(countOne3(a));//6
    } 

    //整数的二进制表达中有多少个1
    public static int countOne(int n){
        int res=0;
        while(n!=0){
            res+=n&1;//每次判断最低位比1与的结果,是1则为1,否则为0
            n>>>=1;//无符号右移一位
        }
        return res;
    }

    public static int countOne2(int n){
        int res=0;
        while(n!=0){
            n&=(n-1);//抹掉右边的1
            res++;//循环次数只与1的个数有关
        }
        return res;
    }

    public static int countOne3(int n){
        int res=0;
        while(n!=0){
            n-=n&(~n+1);//抹掉右边的1;n&(~n+1)是得到n中最右侧的1
            res++;//循环次数只与1的个数有关
        }
        return res;
    }

【无符号右移说明】

int a = -1;
System.out.println(a>>1);//-1
System.out.println(a>>>1);//2147483647
/*
>>>是无符号右移,在高位补零
>>是带符号的右移,如果是正数则在高位补零,负数则补1
1111 1111 1111 1111 1111 1111 1111 1111       -1
1111 1111 1111 1111 1111 1111 1111 1111       -1
0111 1111 1111 1111 1111 1111 1111 1111       2147483647
*/

【与、或、非、异或说明】

1.与运算符
与运算符用符号“&”表示,其使用规律如下:
两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段。

public class data13
{
public static void main(String[] args)
{
int a=129;
int b=128;
System.out.println("a 和b 与的结果是:"+(a&b));
}
}

运行结果
a 和b 与的结果是:128
下面分析这个程序:
“a”的值是129,转换成二进制就是10000001,而“b”的值是128,转换成二进制就是10000000。根据与运算符的运算规律,只有两个位都是1,结果才是1,可以知道结果就是10000000,即128。

2.或运算符
或运算符用符号“|”表示,其运算规律如下:
两个位只要有一个为1,那么结果就是1,否则就为0,下面看一个简单的例子。

public class data14
{
public static void main(String[] args)
{
int a=129;
int b=128;
System.out.println("a 和b 或的结果是:"+(a|b));
}
}

运行结果
a 和b 或的结果是:129
下面分析这个程序段:
a 的值是129,转换成二进制就是10000001,而b 的值是128,转换成二进制就是10000000,根据或运算符的运算规律,只有两个位有一个是1,结果才是1,可以知道结果就是10000001,即129。

3.非运算符
非运算符用符号“~”表示,其运算规律如下:

如果位为0,结果是1,如果位为1,结果是0,下面看一个简单例子。

public class data15
{
public static void main(String[] args)
{
int a=2;
System.out.println("a 非的结果是:"+(~a));
}
}

4.异或运算符
异或运算符是用符号“^”表示的,其运算规律是:
两个操作数的位中,相同则结果为0,不同则结果为1。下面看一个简单的例子。

public class data16
{
public static void main(String[] args)
{
int a=15;
int b=2;
System.out.println("a 与 b 异或的结果是:"+(a^b));
}
}

运行结果
a 与 b 异或的结果是:13
分析上面的程序段:a 的值是15,转换成二进制为1111,而b 的值是2,转换成二进制为0010,根据异或的运算规律,可以得出其结果为1101 即13。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值