位运算常见问题

求n的二进制中1的个数

首先求出这个数的二进制中除最右侧1的那位不变,其余位都是0。
例如:1110,最右侧是1的那个数是0010,0010是如何得出的呢?
记一个小公式:n&((~n)+1)
n=1110带入即可求出最右侧的1的那位数
1110&((~1110)+1)=1110&(0010)=0010
因此计算n的二进制中1的个数就很容易了

public static int bit1Count(int n){
    
    
    int count = 0;
    while(n!=0){
    
    
        rightOne = n&((~n)+1);
        count++;
        n^=rightOne;
    }
    return count ;
} 

如果一个array数组中有两种数字是奇数个,其它数字是偶数个,求出这两种数字

异或运算满足交换律结合律,其实就一句话:异或操作与数字运算的顺序无关,任何一个数异或它本身都等于0。

public void printOddNum2(int[] array){
    
    
    int eor = 0;
    //假设这两种数字是a b
    for(int i=0;i<array.length;i++){
    
    
        eor^=array[i];
    }
    // eor = a^b 只要知道a b中的任何一个就能计算出另一个
    int rightOne = eor&(~eor+1);
    int eor2 = 0;
    // 找这个数二进制的最右侧是1的那位数,因为其他数字是偶数个所以异或之后是0
    for(int i=0;i<array.length;i++){
    
    
        if(array[i]&rightOne==0){
    
    
        // 与运算结果是0,表示当前数字的二进制第n位是0
            eor2^=array[i];
        }
    }
    System.out.println(eor2);
    System.out.println(eor2^eor);
}

Guess you like

Origin blog.csdn.net/qq_43672652/article/details/113820392