认识异或运算

异或运算:相同为0,不同为1
同或运算:相同以1,不同为0

异或运算就记成无进位相加!

1)0^N == N   N^N == 0
2)异或运算满足交换律和结合率

题目一

如何不用额外变量交换两个数

   /**
     * a 与 b 交换数据 不使用中间变量
     */
    public static void m1(){
        int a=5;
        int b=10;
        a=a^b;   //5^10
        b=a^b;   //5^10^10===>5
        a=a^b;   //5^10^5 ===>10
    }

 题目二  

 一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数

/**
 * 数组中只有一个数出现奇数次 其他的是偶数次 找出这个数
 */
public static int m2(int []arr){
    int eur=0;
    for (int a:arr){
        eur^=a;
    }
    return eur;
}

题目三

怎么把一个int类型的数,提取出最右侧的1来

eur&((~eur)+1)

解释:例如一个数是 0001 0001 0011

          取反               1110  1110 1100

           加1                1110 1110 1101

          eur做与操作   0000 0000 0001

题目四
一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数 

/**
 * 数组中有两个数出现奇数次 其他的是偶数次 找出这两个数
 */
public static void m3(int []arr){
    int eur=0;
    for (int a:arr){
        eur^=a;
    }
    int rigthOne=eur&(~eur+1); //找出右边第一个1
    int one=0;
    
    //整个数组分成两个部分 1个部分是在rigthOne位置是1  1个部分是0 所以将两个奇数次的数分开
    for (int i=0;i<arr.length;i++){
        if ((arr[i]&rigthOne)!=0){
            one^=arr[i];
        }
    }
    int two=eur^one;
    System.out.println("这两个数是"+one+two);
}
题目五
如何计算一个数中有几个1
public static void m4(int arr){
int count=0;
while(arr!=0){
int rigthOne=arr&((~arr)+1); //找出右边第一个1
count++;
arr=arr^rigthOne; //还原 统计过的1 变成0
}
System.out.println(count);
}
原文地址:https://www.cnblogs.com/wangyang1991/p/15185956.html