异或运算详解

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);
复制代码

 

posted @   jue1e0  阅读(1172)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
点击右上角即可分享
微信分享提示