异或运算大家都知道指的是对于两个数转准成二进制之后,相同位置上的如果同时为或者,那么异或的结果就是0,不同就是1,比如01异或00结果是01,但是时间长了相信大家都很容易记混,那么有一种很好记的方式,就是:异或其实就是无进位的加法,比如00异或01就是00+01,但是要直接丢弃进位,所以异或运算具有以下特性:
1、任何数与0异或,结果是这个数本身
2、任何数和它自己异或,结果是0
那么异或运算可以解决哪些问题呢
第一题:不用临时变量,交换两个数(其实这个题是很恶心人的,用一个临时变量怎么了)
private void exchange(int a, int b) {System.err.println(a + "->" + b);a = a ^ b;//b的值不变b = a ^ b;//把前面a的值代入,等同于b=a^b^b;a = a ^ b;//把前面a的值代入,等同于b=a^b^a;System.err.println(a + "->" + b);}@Testpublic void testExchange() {exchange(2, 3);}
第二题:给定一个数组,只有一个数在其中出现了奇数次,其他的数出现偶数次,找出这个数
思路:用一个临时变量tmp,初始值为0,从数组开头一直异或到结尾,最后tmp就是要找的数
举个例子[1,2,3,4,1,2,4],我们要找的数据是3,根据前面的结论,任何一个数异或0等于它本身,同一个数异或它自己等于,那么这个数组其实我们把它排序看看[1,1,2,2,3,4,4],所以1,2,4在与tmp异或完之后tmp等于0,最终结果就是3了
private int findOddNumTimes(int[] arr) {int tmp = 0;for (int i : arr) {tmp = tmp ^ i;}return tmp;}@Testpublic void testfindOddNumTimes() {System.err.println(findOddNumTimes(new int[]{1, 2, 3, 4, 1, 2, 4}));}