异或运算详解
1.异或运算的基本性质:
两个数的异或可以看做两个数进行不进位的加法
(1).0^n = n, n ^ n = 0, 1^n = ~n
(2).满足交换律:a^b = b^a 满足结合律:(a^b)^c = a^(b^c)
(3).从(2)中可以推出,只要是同一批数进行异或,那么任意调换异或顺序,不改变最终的结果
2.异或运算的实例运用:
(1).异或实现数据交换
使用前提:a,b不指向同一块内存,否则a,b会全部置为0
1 private static void swap(int a,int b) { 2 a = a ^ b; 3 b = a ^ b; 4 a = a ^ b; 5 }
解析:设a=甲 b=乙
则第2行时候:a=甲^乙 b=乙
第3行时候:a=甲^乙 b=甲^乙^乙=甲^0=甲
第4行时候:a=甲^乙^甲=0^乙=乙 b=甲
(2).若一批数中,所有数据中只有一种数据出现了奇数次,其他均为偶数次,快速找出这个出现奇数次的数
直接将数组中所有数组进行异或即可得到该数
1 public static int FindOneOddTimes(int[] arr) 2 { 3 int ans = 0; 4 for (int i = 0 ;i <arr.length ;i++) 5 { 6 ans ^= arr[i]; 7 } 8 return ans; 9 }
若有两种数据出现了奇数次,找到这两个数:
设这两个数分别为a和b
则得到的结果eor = a^b;因为a!=b,所有eor必定有一位为1,而这也意味着a和b在这一位上不想同
设该位为第i位,则此时,选择异或所有第i位为1的数,所得的结果eor1就是a和b的某一个
再次选择异或所有第i位为0的数,所得的结果eor2就是a和b的另外一个
1 public static void FindTwoOddTimes(int[] arr) 2 { 3 int ans1 = 0,ans2 = 0; 4 int eor = 0; 5 for (int i = 0; i < arr.length ; i++) 6 { 7 eor ^= arr[i]; 8 } 9 10 int rightOne = eor & (~eor + 1);//eor与eor的补码相与即可获得其最右位为1其余位均为0的值 11 //如:eor为101100100,则通过该行得到000000100 12 13 for (int i = 0 ; i < arr.length; i++) 14 { 15 if ((arr[i] & rightOne) != 0) 16 { 17 ans1 ^= arr[i]; 18 } 19 else 20 { 21 ans2 ^= arr[i]; 22 } 23 } 24 System.out.println(ans1 + " "+ ans2);
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)