性质:

a. 0^n=n n^n=0

b. 满足交换律和结合律

a^b=b^a a^b^c=a^(b^c)

c. 同一批数进行异或,无关顺序,选择任何两个数先异或得到的数相同

题:

a.有一个int数组,里面有一种数是奇数次,其余为偶数次,找出这种数字

  1. public static void odd1(int[] arrys) {
  2. if (arrys.length < 2) {
  3. return;
  4. }
  5. int err = 0;
  6. for (int arr : arrys) {
  7. err ^= arr;
  8. }
  9. System.out.println(err);
  10. }

b.有一个int数组,里面有两种数是奇数次,其余为偶数次,找出这两种数字

  1. /**
  2. * 0.假如测试用例为[1,2,3,1]
  3. * @param arrys
  4. * @return
  5. */
  6. public static void odd2(int[] arrys) {
  7. if (arrys.length < 2) {
  8. throw new RuntimeException();
  9. }
  10. //1.因为有两种数是奇数次,所以err结果为这两种数的异或
  11. //即2^3,二进制表示为10^11即01,此时err=1
  12. int err = 0;
  13. for (int arr : arrys) {
  14. err ^= arr;
  15. }
  16. //2.取出err最右侧为1的一位,表明两个奇数是在这一位上是不同的
  17. //~是取反的意思
  18. //01&(10+01)=01&11=01
  19. int rightOne = err & (~err + 1);
  20. int err2 = 0;
  21. //3.此时重新遍历数组,将数组分为两组
  22. //一组为与rightOne相与为0
  23. //一组为与rightOne相与不为0
  24. //即使不是奇数次的数字能够进入判断进行异或也会两两抵消这样会得到其中一个奇数
  25. for (int arr : arrys) {
  26. if ((arr & rightOne) == 0) {
  27. err2 ^= arr;
  28. }
  29. }
  30. System.out.println(err2 + "-" + (err ^ err2));
  31. }