今日份牛客==二进制中1的个数==原码补码二进制移位操作

来源:牛客 https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=188&&tqId=36702&rp=1&ru=/ta/job-code-high-week&qru=/ta/job-code-high-week/question-ranking
声明:如果我侵犯了任何人的权利,请联系我,我会删除
欢迎高手来喷我

题目 二进制中1的个数

题目描述
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
输入 10
返回值 2

== 这里的示例并不全,缺少负数的==
我自己添加的示例:

输入 -1 输出 32
输入-2147483648 输出1

大神的代码:

就一句话: 即n&(n-1) 会消去n最右边的1(也就是从右向左的第一个1)。循环中,每次消去n的一个1,n==0时没有1了就退出

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

public int NumberOf1(int n) {
    
      
      int ans = 0;
        while (n != 0) {
    
    
            ++ans;
            n = n & (n-1);
        }
        return ans;
    }
普通的思路就是计算每一位是不是1

这里用的是 >>>无符号右移,即无论正数还是负数,都用0补齐

    public int NumberOf1(int n) {
    
    
        int count = 0;
        while(n != 0){
    
    
            count += (n & 1); //每次判断最低位是否为1
            n >>>= 1;
        }
        return count;
    }
稍微说一点java二进制的这个和那个
原码和补码
  • 正数的二进制是原码,即3 = 011
  • 负数的二进制是补码,就是符号位不变,原码取反加1得到的补码,即-3 = 1 1101
  • String string = Integer.toBinaryString(n);java中用这个操作可以得到n的二进制表示:
  • 如下图,这里最左边的0被省略了- 在这里插入图片描述
二进制移位 >>,<<,>>>

这里就涉及到移位操作了,先来看看二进制的移位操作>>,<<,>>>,<<<(关键是负数的移位有点特别)因为负数的符号位在最左边,右移的时候有点…

  • << 向左移,二进制的结尾就直接用0来补全了,没有正负之分,因为这里都是补0,也因为负数的符号位在最左边
  • >> 向右移,有两种情况:开头以符号位补全
    • 负数就是用1补全,比如-5的二进制是1111…1011, 右移两位 11 1111…10
    • 正数开头以0补全
  • >>>都是无符号的移位操作,不论是右边补齐还是左边补齐都用0
  • <<< 是没有这个操作的,为什么,无符号右移和 << 没有区别

int n = 5;
int m = -5;
System.out.println(“n的二进制:”+Integer.toBinaryString(n));
System.out.println(“m的二进制:”+Integer.toBinaryString(m));
System.out.println("n>>2: "+Integer.toBinaryString((n>>2)));
System.out.println("m>>2: "+Integer.toBinaryString((m>>2)));
System.out.println("n<<2: "+Integer.toBinaryString((n<<2)));
System.out.println("m<<2: "+Integer.toBinaryString((m<<2)));
System.out.println("n>>>2: "+Integer.toBinaryString((n>>>2)));
System.out.println("m>>>2: "+Integer.toBinaryString((m>>>2)));
在这里插入图片描述

含二进制运算符的优先级

在这里插入图片描述

参考博客

Java中补码与反码:
https://blog.csdn.net/weixin_37870009/article/details/79775926?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1.control

java 原码、反码、补码计算 以及 取反(~)运算 :
https://blog.csdn.net/u010841296/article/details/52850307

java中操作二进制的运算符总结(&,| , ^, ~, <<,>>, >>> ):
https://blog.csdn.net/xinghuo0007/article/details/78453442

总结一下java中的位操作,运算优先级:
https://blog.csdn.net/sadjladjlas/article/details/51192106

java学习笔记-获取正数的原码和负数的补码:
https://blog.csdn.net/u010503427/article/details/79631121

猜你喜欢

转载自blog.csdn.net/qq_45531729/article/details/110949414