package class02; /** * 1.在arr中,只有一种数字,出现了奇数次,其余的数都出现了偶数次。找出这个出现了奇数次的数字。 * 2.在arr中,有两种数字,出现了奇数次,其余的数都出现了偶数次。找出这两种出现了奇数次的数字。 */ public class Code02_EvenTimesOddTimes { public static void main(String[] args) { int[] arr = {1, 1, 2, 2, 3, 5, 5, 6, 6, 8, 8};//3出现了奇数次 int[] arr2 = {1, 1, 2, 2, 6, 6, 6, 12, 12, 12};//6和12出现了出现了奇数次 printOddTimesNum1(arr); printOddTimesNum2(arr2); } /** * 在arr中,只有一种数字,出现了奇数次,其余的数都出现了偶数次。找出这个出现了奇数次的数字。 * * @param arr */ private static void printOddTimesNum1(int[] arr) { int a = 0; for (int num : arr) { a ^= num; } System.out.println("a = " + a); } /** * 在arr中,有两种数字,出现了奇数次,其余的数都出现了偶数次。找出这两种出现了奇数次的数字。 * * @param arr */ private static void printOddTimesNum2(int[] arr) { int eor = 0; for (int i = 0; i < arr.length; i++) { eor ^= arr[i]; } System.out.println("eor = " + eor);//eor:a^b
int rightOne = eor & (-eor);//最右侧的1 System.out.println("rightOne = " + rightOne); int onlyOne = 0;//eor' //算出rightOne后,我们就可以把arr中的所有的数,分成两类: //一类:rightOne为1的这一位,为1的数。 //另一类:rightOne为1的这一位,为0的数。 for (int i = 0; i < arr.length; i++) { //(arr[i] & rightOne) != 0,的意思是: //onlyOne要和arr数组中的谁进行异或操作呢?要和满足这个条件的数。 //那么满足这个条件的数,都是什么数呢? //都是:对于arr[i],在rightOne为1的这一位,是1的数。因为如果不是1,即是0的话,&之后的结果就是0。 if ((arr[i] & rightOne) != 0) {//关键代码,&后结果等于0,则说明arr[i]的这一位是0。&后结果不等于0,则说明arr[i]的这一位是1。 onlyOne ^= arr[i]; } } //走完循环后,此时onlyOne即eor',就是a或者是b。 //也就是onlyOne抓到了,区域1中的,出现了奇数次的那个数,不是a就是b。 //而eor是a^b,所以onlyOne ^ eor就是:a^(a^b),或者b^(a^b)。即a和b中另外一个。 System.out.println(onlyOne); System.out.println(onlyOne ^ eor); } private static void printOddTimesNum3(int[] arr) {//只是去掉了注释 int eor = 0; for (int i = 0; i < arr.length; i++) { eor ^= arr[i]; } System.out.println("eor = " + eor);//eor:a^b int rightOne = eor & (-eor);//最右侧的1 System.out.println("rightOne = " + rightOne); int onlyOne = 0;//eor' for (int i = 0; i < arr.length; i++) { if ((arr[i] & rightOne) != 0) { onlyOne ^= arr[i]; } } System.out.println(onlyOne + ", " + (onlyOne ^ eor)); } }
标签:arr,数字,rightOne,int,eor,数次,onlyOne From: https://www.cnblogs.com/TheFloorIsNotTooHot/p/16838672.html