一文搞懂 位运算 异或(Java实现)

article/2025/10/6 8:25:37

        提起异或想必很多小伙伴们既熟悉又陌生,熟悉是因为好像在离散数学或者学某个编程语言

时听过这个东西,而陌生呢,则是因为自己平时并没有用过,以至于当在某个场景 (我猜是在看

题解或者某篇博客时)  看到这个名词的时候很懵逼,因此才会幸运地看到这里,那么请继续往下

看吧。


目录

一. 什么是异或呢?

二. 异或有哪些运算法则呢?(不用背,下面会有例子帮助理解) 

三.计算机底层是怎么进行异或运算的呢?

四.异或有什么妙用?

1. 我们来看一道leetcode上的题目

2. 两个数字交换

3. 两个数字判等

4. 加密

5. 备份

五.最后的话

一. 什么是异或呢?

        异或是位运算的一种,属于逻辑运算符,是一种二进制运算。在计算机中用符号XOR 或 ^ 来

表示,数学中则用 ⊕ 表示。

        众所周知,程序中的所有数据在计算机内存中都是以二进制的形式存储的。因此异或直接处

理的是二进制数字 0 和 1 。异或最基础的运算法则为: 0 ⊕ 0 = 0,1 ⊕ 0 = 1,0 ⊕ 1 = 1 ,1 ⊕ 1 =

0   一句话简单概括就是  相同为 0 ,不同为 1 。 


二. 异或有哪些运算法则呢?(不用背,下面会有例子帮助理解) 

        1. 归零律: a  ⊕  a  = 0   

        2. 恒等律: a  ⊕  0  = a            

        3. 交换律: a  ⊕  b = b  ⊕  a

        4. 结合律: a  ⊕  b  ⊕  c  =  a ⊕ ​​​​​​ ( b  ⊕ ​ ​​​​​​c ) = ( a  ⊕  b )  ⊕ c

        5. 自   反:  a ⊕ b ⊕ a = b

        6.  d = a ⊕ b ⊕ c   可以推出   a  =  d  ⊕  b  ⊕  c.  


三.计算机底层是怎么进行异或运算的呢?

        现在有三个数字 a b c   其对应的十进制和二进制已经给出

        a = 10= 1010   b = 8 = 1000  c = 12 = 1100 

        我们已经知道计算机内存中以二进制存储数据,因此在进行异或运算时,计算机先把十进制

数字转换为二进制数字再进行相应的运算。如下面的几个例子,计算机一位一位地进行异或运算

相同为0,不同为1),之后将每一位计算得到的结果合在一起,即是最终结果。

        a ⊕ a =     1 0 1 0
                     ⊕ 1 0 1 0
                     =  0 0 0 0


        a ⊕ 0 =     1 0 1 0
                     ⊕ 0 0 0 0
                     =  1 0 1 0


        a ⊕ b =     1 0 1 0
                     ⊕ 1 0 0 0
                     =  0 0 1 0

        a ⊕ b ⊕ c  =     1 0 1 0
                                 1 0 0 0
                             ⊕ 1 1 0 0
                             =  1 1 1 0

        a ⊕ b ⊕ a  =      1 0 1 0
                                  1 0 0 0
                              ⊕ 1 0 1 0
                              =  1 0 0 0


四.异或有什么妙用?

1. 我们来看一道leetcode上的题目

           第136题 只出现一次的数字https://leetcode.cn/problems/single-number/

 这道题是要我们找出来数组中只出现一次的数字

 注意要求:时间复杂度O(n)   空间复杂度O(1) 

1.1 哈希表   (时间复杂度O(n)   空间复杂度O(n) )

        我看到这个题的第一思路就是用哈希表。这是这种题目通用的解法,利用哈希表的特性很容

易区分重复的和不重复的。

         但是此时,时间复杂度O(n)   空间复杂度O(n)   并不满足题目要求 

class Solution {public int singleNumber(int[] nums) {HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {//获取当前数组中的数字在哈希表中的个数  如果没有则返回nullInteger integer = map.get(nums[i]);if (integer == null)//当前哈希表中没有该数字map.put(nums[i], 1);//加入哈希表中,数量 = 1elsemap.put(nums[i], integer + 1);//当前哈希表中已存在该数字,数量+1}Set<Integer> integers = map.keySet();for (Integer integer : integers) {//获取当前哈希表中各个数字的个数  个数为 1 的话即为所求。if (map.get(integer) == 1)return integer;}return -1;}
}

1.2 暴力双重循环    (时间复杂度O(n2)   空间复杂度O(1) )

        然后就想到暴力的方式了,但是要用到两重循环 ,这个时候的时间复杂度就是 O(n2) 了,也

不满足要求。

此处代码省略

1.3 快排    (时间复杂度O(nlogn)   空间复杂度O(1) )

        去看题解发现还可以先排序,然后再遍历找第 i 个数字和第 i + 1 个数字不相同的,当然此处

遍历的时候就是 i = i + 2   而不是 i++ 了,但是排序算法中没有 时间复杂度是O(n) 的,即便是快速

排序,其时间复杂度也是O(nlogn) ,因此也解决不了问题

        for(int i=0;i<nums.length;i+=2){//}

 1.4 异或     (时间复杂度O(n)   空间复杂度O(1) )

        用异或来解决这个问题就很美妙了。

class Solution {public int singleNumber(int[] nums) {int ans = nums[0];if (nums.length > 1) {for (int i = 1; i < nums.length; i++) {//循环结束后ans 就等于数组中所有元素异或后的结果ans = ans ^ nums[i];}}return ans;}
}

        我们能够看到用异或来处理这个问题效率尤其的高。不需要像哈希表那样占用额外的空间,

也不用双重循环。真是优雅之极。

        可能有的小伙伴不理解为什么要用异或解决这个问题,异或是怎么解决这个问题的。下面我

们就来好好说说异或处理这样的问题的美妙之处。

        首先由前面我们已经知道,异或处理两个相同的数据时,得到的结果为0,而且异或的顺序是

可以交换的,交换并不会影响异或的最终结果,所以数组中所有元素异或之后,交换元素顺序,两

两相同的结合进行异或,通过异或运算我们会知道每两个相同的数字异或之后的结果为0,而多组0

之间异或后最后还剩一个0,然后就剩下那个只出现一次的数字和0之间进行异或,而由前面我们知

道任何数字和0异或结果为该数字,自此我们得到了所求结果,整个过程只需要一次循环去求数组

中所有元素之间的异或即可,优雅不优雅,美妙不美妙。

        以上仅为证明这个方法可以得到最终结果,计算机会按照先后顺序依次进行异或。

        下面是也是个关于异或的题目,有余力的可以尝试用异或做做看,很有意思的。第260题 只出现一次的数字Ⅲhttps://leetcode.cn/problems/single-number-iii/

2. 两个数字交换

        通常,我们引用一个变量去交换,但这会浪费一个空间。而如果通过异或的话就不需要占用

一个空间。

        int a = 30;int b = 23;if (a > b) {a = a ^ b;b = a ^ b;a = a ^ b;}

3. 两个数字判等

        我们已经知道当两个数字相等时,异或结果为0;因此我们可以利用这个特性去判等,效率更

高哦!

        

    a^b==0//与a==b一个意思

4. 加密

        在这里我们要拓展一下下面这个运算法则

        ①d = a ⊕ b ⊕ c   可以推出   ②a  =  d  ⊕  b  ⊕  c.  

        我们已经知道由 ① 可以推出 ② ,其实还可以推出 a  ⊕  b = c  ⊕  d

        此外,由 ① 推出 ② 我们可以知道 当我们得到其中的任意三个都可以推出另外一个

        同理,在 c = a ⊕ b 中我们也可以由其中的任意两个来推出另外一个

        这就引出了我们这里的内容,加密信息。

        在密文a 、密匙b 、明文c三者之间我们也可以利用异或来实现信息的加密。

        发送方可以通过密文异或密匙,来得到一篇明文发送给接收方,即 a ^ b = c 。

        而接收方则可以通过密匙和明文异或获得密文,即 b ^ c = a

        由此,我们就实现了信息的加密。

5. 备份

        同样的,利用上面推出的结论,我们也可以备份文件,那么怎么备份呢?让我们好好想想,

上面说到当我们得到三者中的任意两者就可以得到另外一个。那么我们是不是也可以设计一种类似

与密匙的东西,通过他的处理,我们将需要备份的文件与密匙异或得到一个恢复包。这样在原始文

件丢失的情况下,我们就可以通过密匙与恢复包异或得到丢失的文件。

五.最后的话

        第一次写博客,个别地方还不够完善,也参考了部分别人写的博客里的内容,如有什么错误

的地方,希望大家可以批评指正,也希望大家可以补充更多相关的内容,让我们共同进步,一起加

油吧!

参考如下:

https://blog.csdn.net/qq_19272431/article/details/78564391

https://blog.csdn.net/cuixianlong/article/details/90064348

https://zhuanlan.zhihu.com/p/453673815


http://chatgpt.dhexx.cn/article/eC7644I8.shtml

相关文章

java中异或运算的应用

java中异或运算(^)的应用 异或运算法则 1. a ^ b b ^ a   2. a ^ b ^ c a ^ (b ^ c) (a ^ b) ^ c;   3. d a ^ b ^ c 可以推出 a d ^ b ^ c.   4. a ^ b ^ a b. 异或运算 1、异或是一个数学运算符。应用于逻辑运算。   2、例如&#xff1a;真异或假的结果是…

java的异或运算

一、题目 输入两个数&#xff0c;交换后输出 二、解题思路 一开始学习的语言是c语言&#xff0c;里面非常有特色的是指针&#xff0c;通过传引用可以直接交换两个数。但java无法达成这种操作&#xff0c;翻阅资料找到了一种有趣的解法&#xff1a;异或! 异或原理&#xff1a; …

java基础-异或运算

小伙伴们&#xff0c;你们好呀&#xff01;我是老寇&#xff01; 异或运算主要用于判断两个值是否一样 异或运算的3个性质&#xff1a; 1.任何数和0进行异或运算&#xff0c;结果是原来的数&#xff0c;即b⊕0b 2.任何数和其自身进行异或运算&#xff0c;结果为0&#xff0c;即…

Java中的异或运算符^

Testpublic void test2() {int a2;int b3;aa^b;ba^b;aa^b;System.out.println("a"a",b"b);}第一种&#xff1a;用真实值计算 ^是异或运算符&#xff0c;异或的规则是转换成二进制比较&#xff0c;相同为0&#xff0c;不同为1. 一个数a与另一个数b异或的结果…

java中的异或运算

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是Rockey&#xff0c;不知名企业的不知名Java开发工程师 &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;联系方式&#xff1a;he18339193956&…

HTTP Status 505 – HTTP Version Not Supported

这个大部分的原因不是httpserver不支持&#xff0c;而是请求url里有空格&#xff0c;检查有空格UTF-8编码再传 比如&#xff1a;远程调用服务端地址有空格 去除空格

HTTP Status 500 解决办法

HTTP Status 500 解决办法 在Java web 论坛系统中也遇见了这个问题&#xff0c;在这里就提供一个解决的办法。 图中显示 int idInteger.parseInt(request.getParameter("id")); 这一段有错误。这里是因为id的值不能为null&#xff0c;不然就会出现这个错误 修改如…

Tomcat HTTP Status 404 tomcat 404问题解决

今天初次使用tomcat的时候&#xff0c;用浏览器访问总是不成功。经过一番周折总算成功了&#xff0c;虽然这个知识点不是很难&#xff0c;但还是写篇博客&#xff0c;希望能帮助那些初学者。(注&#xff1a;笔者用的是&#xff1a;tomcat 7) 前提&#xff1a;你的tomcat可以访…

svn提交报错Unexpected HTTP status 413 'Request Entity Too Large' on

问题原因&#xff1a;nginx的client_max_body_size设置过小&#xff0c;默认 1M&#xff0c;如果请求的正文数据大于client_max_body_size&#xff0c;HTTP协议会报错 413 Request Entity Too Large。 解决方案&#xff1a;把这个值调大就可以了。

HTTP Status 404 - 解决办法

HTTP Status 404 - 解决办法 今天&#xff0c;我在从仓库导入web项目的时候出现了一个问题&#xff1a; 首先&#xff0c;我想的是为什么会出现&#xff0c;这样的问题&#xff0c;然后我对这个问题进行了描述&#xff0c;准备在网上找找解决方法&#xff0c;大多数给出的答案…

HTTP Status 500 – Internal Server Error

第一次碰到500错误,标题很明显,内部服务器错误,解决此类问题重点在于会看错误提示信息,之前一直没有这个意识,看到报错直接百度,其实我们稍微注意一下信息提示就能解决大部分问题,上图: 看下第二条Message,标注了/iframe/head.jsp页面,后边括号表明为第一行第二列(个…

HTTP Status 400的排错步骤 与HTTP Status 404的排错步骤

一、前言&#xff1a;一个问题有暗含两个错误&#xff1a;400和404 二、HTTP Status 400 这是在跳转修改的界面出现&#xff0c;跳不过去说明路径相关有问题 上面 400的解决了&#xff0c;然后运行404又出来了 三、HTTP Status 404 看到资源问题&#xff0c;就去看下导包没有&a…

SpringBoot 设置HTTP 响应状态码 (HTTP Status Code)

SpringBoot 设置HTTP 响应状态码 (HTTP Status Code) HTTP请求响应的内容有很多&#xff0c;包括Body、Cookies、Headers和Status。 我们最常用的是Body、其次Headers、Cookies。而HTTP Status Code关注得最少。 HTTP Status Code 分类分类描述1**信息&#xff0c;服务器收…

HTTP Status 500 - null

出现这类问题&#xff1a;The server encountered an internal error that prevented it from fulfilling this request. java.lang.Integer.parseInt(Integer.java:542) HTTP Status 500 - null 500错误是首先考虑java代码的问题&#xff0c;如果不是java代码的问题的话&#…

Http Status 500

这个错误一般都是空指针异常 错误信息页面一般都提示了错误的页面和行数 我的SearchCondition java:25是这样的 我的name值是空的&#xff0c;然后后面用到了name,所以报了空指针异常&#xff1b; 像大型的项目&#xff0c;可以采取以下的措施&#xff1a; 一、通过System.…

HTTP Status 500 - Internal Server Error

Http请求状态码 200&#xff1a;正常404&#xff1a;资源找不到400&#xff1a;请求类型不匹配500&#xff1a;后台程序抛出异常游览器抛出的异常其实跟最基础的JAVA程序抛出异常是相似的只是异常提醒出现的位置不同&#xff0c;外加给了异常类型的数字&#xff08;200&#xf…

HTTP Status Codes/HTTP状态码

1.应用场景 帮助快速查询http code, 以及对应的含义&#xff0c;帮助定位问题。 2.学习/操作 推荐查阅 HTTP Status Codes Glossary - WebFX STATUS_CODES { 100: Continue, // 持续中 101: Switching Protocols, // 转换协议 102: Processing, // 进行中 200: OK, …

华为eNSP下的ssh配置实验

配置两台路由器&#xff08;AR4为服务器&#xff0c;AR3为SSH客户端&#xff09; 修改R3为AR3&#xff0c;修改R4为AR4&#xff0c;AR3地址192.168.1.1&#xff0c;AR4地址为192.168.1.2 发现能互通 配置aaa模式用户名加密码 设置权限等级 创立RSA的ssh秘钥 只允许ssh进…

WSL中的SSH配置方法

本地主机win11系统&#xff0c;wsl2:Ubuntu 20.04.4 LTS 1&#xff0c;更新linux $ sudo apt-get update lili:~$ sudo apt-get update [sudo] password for li: Ign:1 http://mirrors.ustc.edu.cn/ubuntu precise-updates InRelease Ign:2 http://mirrors.ustc.edu.cn/ubu…

ssh配置文件和ssh命令

ssh&#xff1a;发送数据&#xff0c;并对数据进行加密。默认端口22 &#xff0c;Secure Shell ssh远程管理登录命令 ssh rootIP 以root用户登录IP这台主机实验中&#xff0c;通过虚拟机中的centos7(作为客户端)去远程登录阿里云管理的主机(作为服务器端),因为ssh是利…