异或是一种基于二进制的位运算,同值取0,异值取1。
性质
1、交换律
2、结合律(即(a^b)^c == a^(b^c))
3、对于任何数x,都有x^x=0,x^0=x
4、自反性 A XOR B XOR B = A xor 0 = A
运用:
1.变量交换
A=A XOR B (a XOR b)
B=B XOR A (b XOR a XOR b = a)
A=A XOR B (a XOR b XOR a = b)
例:
int a = 10, b = 5
a = a ^ b;
b = a ^ b;
a = a ^ b;
2.获取唯一的重复元素
1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?
解法一、显然已经有人提出了一个比较精彩的解法,将所有数加起来,减去1+2+...+1000的和。
这个算法已经足够完美了,相信出题者的标准答案也就是这个算法,唯一的问题是,如果数列过大,则可能会导致溢出。
解法二、异或就没有这个问题,并且性能更好。
将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数。
首先是异或运算满足交换律、结合律。所以,1^2^...^n^...^n^...^1000,无论这两个n出现在什么位置,都可以转换成为1^2^...^1000^(n^n)的形式。
其次,对于任何数x,都有x^x=0,x^0=x。所以1^2^...^n^...^n^...^1000 = 1^2^...^1000^(n^n)= 1^2^...^1000^0 =1^2^...^1000(即序列中除了n的所有数的异或)。令,1^2^...^1000(序列中不包含n)的结果为T则1^2^...^1000(序列中包含n)的结果就是T^n。T^(T^n)=n。
所以,将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数。
3.获取唯一不重复数
一个数组存放若干整数,一个数出现奇数次,其余数均出现偶数次,找出这个出现奇数次的数?
@Test
public void fun() {
int a[] = { 22, 38,38, 22,22, 4, 4, 11, 11 };
int temp = 0;
for (int i = 0; i < a.length; i++) {
temp ^= a[i];
}
System.out.println(temp);
}