文章目录
一、异或运算的性质与扩展
1)无进位相加
1.无论这个数是什么,只要它与零异或,它就会使本身。因为1^0=1 , 0 ^ 0=0; 2.任何数与自己本身想异或结果为零 N^N=0; 3.异或运算可以理解为无进位的相加2)异或运算的性质
1.N^0=N ;N ^ N =0; 2.满足交换律和结合律 a^b=b ^ a ; a ^ b ^ c = a ^ (b ^ c) 3.无论怎么排列一堆数,他们异或总起来总会是一个数,因为可以用交换律将他们组合成一个异或3)不用额外变量交换两个数
代码如下:
int a=3; int b =4;
a=a^b;
b=a^b;
a=a^b;
### 设计的思想
特别特别注意一定要求交换的两个东西的地址是不同的,值可以一样,但是内存必需不是一个东西。一旦相等就出问题了
4)一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数
算法设计思路
将数组的所有数值异或到同一个值上
这样,出现偶数次的全部变成零,出现奇数次的就成为剩下的
代码
public static void find1(int [] arr) {
int e = 0;
for(int cur : arr) {
e ^= cur;
}
System.out.println(e);
}
5)一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到这两个数
算法设计思路
首先异或一次得到两个数的异或结果
然后用这个异或结果对数组进行分类
分类的方法,找出一个二进制位为一的位
在这个位上,两个出现奇数次的数字,值必不相同。
然后但独将两个类分别异或,则得到值
也可以用得到的一个值与一开始异或的值进行异或。即可得到该值。
代码
public static void find2(int [] arr) {
int eo = 0;
for(int cur : arr ) {
eo ^= cur;
}
int rone = 0;
rone = eo &(~eo + 1);
int a = 0 ,b = 0;
for(int cur : arr ) {
if((cur & rone)==0) {
a ^= cur ;
}
b=a^eo;
}
}