位操作(Bit Manipulation)—— Hamming Distance

目录

题目:

思路:

要点:

1、如何计算整数的二进制表示中有几个1?

解法:

补充:

1、负数的二进制表示方法

2、将1左移多少次会变成0?

3、位运算的优先级


题目:

略;

思路:

先将输入的两个数做异或运算,得到结果n,再统计n二进制序列中有几个1.

要点:

1、如何计算整数的二进制表示中有几个1?

方法一:解释见方法注释;注意这里对1进行左移运算,而不是对num进行右移运算,负数的二进制表示见补充一;while循环的条件是flag!=0,那么一共循环了多少次?见补充二。

    /*
        对于一个整数,和1做与运算,如果为0,则最低位为0;
        随后将1左移(这里不将num右移,是因为num有可能是负数)
    */
    private int getOnes(int num){
        int count = 0;
        int flag = 1;
        while(flag!=0){
            if((num&flag) != 0)
                count++;
            flag = flag<<1;
        }
        return count;
    }

方法二:解释见方法注释

    /*
        优化解法
        对于一个整数(比如10,用二进制表示为1010),将这个整数减1,变成9(用二进制表示就是1001)
        这个过程就是将10最低位上的1以及其后所有的位取反,这些位置在将n和n-1(10和9)做与操作之后,都变成0
    */
    private int getOnes2(int num){
        int count = 0;
        int flag = 1;
        while(num!=0){
            count++;
            num = num&(num-1);
        }
        return count;
    }

解法:

class Solution {
    public int hammingDistance(int x, int y) {
        int inputNum = x^y;
        return getOnes2(inputNum);
    }
    
    
    /*
        对于一个整数,和1做与运算,如果为0,则最低位为0;
        随后将1左移(这里不将num右移,是因为num有可能是负数)
    */
    private int getOnes(int num){
        int count = 0;
        int flag = 1;
        while(flag!=0){
            if((num&flag) != 0)
                count++;
            flag = flag<<1;
        }
        return count;
    }
    
    /*
        优化解法
        对于一个整数(比如10,用二进制表示为1010),将这个整数减1,变成9(用二进制表示就是1001)
        这个过程就是将10最低位上的1以及其后所有的位取反,这些位置在将n和n-1(10和9)做与操作之后,都变成0
    */
    private int getOnes2(int num){
        int count = 0;
        int flag = 1;
        while(num!=0){
            count++;
            num = num&(num-1);
        }
        return count;
    }
    
    public int numberOf1(int n){
        int count = 0;
        int count1= 0;
        int flag = 1;
        while(flag!=0){
            if((n&flag)!=0){//位运算符的优先级问题
                count++;
            }
            flag = flag<<1;
            count1++;//一共循环32次
        }
        return count;
    }
}

ps:函数numberOf1是用来测试循环多少次的。

补充:

1、负数的二进制表示方法

以负数-5为例:

  •     先将-5的绝对值转换成二进制,即为0000 0101;
  •     然后求该二进制的反码,即为 1111 1010;
  •     最后将反码加1,即为:1111 1011

    ps:所以Java中Integer.toBinaryString(-5)结果为11111111111111111111111111111011. Integer是32位(bit)的.

2、将1左移多少次会变成0?

实验证明,左移32次或超过32次,会变成0.

3、位运算的优先级

ps:一元运算符>四则(包括%)>位移运算符>比较运算符(包括instanceof)>位逻辑运算符>逻辑运算符>三目运算符>赋值运算符;参考 位运算符优先级

猜你喜欢

转载自blog.csdn.net/qq_24888697/article/details/82178003