020730 发表于 2022-11-11 11:09:36

关于异或的运用问题

问题:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
疑问:这个代码是正确的,但是自己不太理解

public class Test06 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
      //给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
      int[] arr = {1,8,2,3,5,3,2,8,1};
      int cnt = findNum(arr);
      System.out.println("只出现了一次的元素为:"+arr);
    }
    //老师的代码--->还未懂
    public static int findNum(int[] a){
      int ret = a;
      for(int i=1;i<a.length;i++){
            ret ^= a;
      }
      return ret;
    }
}

jackz007 发表于 2022-11-11 11:37:54

本帖最后由 jackz007 于 2022-11-11 13:50 编辑

a ^ b 两个数对应二进制位做异或,如果对应位相等得 0,不相等得 1,例如:

171 ^ 229 = 0xab ^ 0xe5 = 0x4e = 78

1 0 1 0 1 0 1 1   0xab = 171
1 1 1 0 0 1 0 1   0xe5 = 229
----------------
0 1 0 0 1 1 1 0   0x4e =78
      两个相同的数作异或,得到的值一定是 0,二进制位的异或是有累积效应的
      所以,55 ^ 127 ^ 8 ^ 55 ^ 127 = 8
      对于
      int[] a = {1,8,2,3,5,3,2,8,1} ;
      int ret = a;
      for(int i=1;i<a.length;i++){
            ret ^= a;
      }
      就是 a 的 8 个元素连续做异或:ret = a ^ a ^ a ^ a ^ a ^ a ^ a ^ a ^ a
0 0 0 0 0 0 0 1   1a
0 0 0 0 1 0 0 0   8a
----------------
0 0 0 0 1 0 0 1   9ret
0 0 0 0 0 0 1 0   2a
----------------
0 0 0 0 1 0 1 1    11ret
0 0 0 0 0 0 1 1   3a
----------------
0 0 0 0 1 0 0 0   8ret
0 0 0 0 0 1 0 1   5a
----------------
0 0 0 0 1 1 0 1    13ret
0 0 0 0 0 0 1 1   3a
----------------
0 0 0 0 1 1 1 0    14ret
0 0 0 0 0 0 1 0   2a
----------------
0 0 0 0 1 1 0 0    12ret
0 0 0 0 1 0 0 0   8a
----------------
0 0 0 0 0 1 0 0   4ret
0 0 0 0 0 0 0 1   1a
----------------   
0 0 0 0 0 1 0 1   5ret
      最后结果 ret = 5 ,说明 a 的 9 个元素中,只有 5 是单次出现的。

一颗yan 发表于 2023-1-5 17:49:06

二楼神解,谢谢知识分享。楼主这里打印错了System.out.println("只出现了一次的元素为:"+cnt);
页: [1]
查看完整版本: 关于异或的运用问题