欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-27 15:41:21
...

【题目】

给定一个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。