认识异或运算
异或运算:相同为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);
}