异或运算在算法中的神奇应用

这篇具有很好参考价值的文章主要介绍了异或运算在算法中的神奇应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 什么是异或

两个二进制数进行异或运算时,每一位上的数相同则结果为0,不同则结果为1。

示例:6^7=?

转化成二进制:
6=110
7=111
6^7=110^111=001=1

简单记:异或就是二进制的无进位相加。
还有个同或运算:相同为1,不同为0,和异或是反的。

2. 异或运算的特性

  1. 任何数与0异或,结果还是这个数:0^n=n
  2. 任何数与自身异或,结果都是0:n^n=0
  3. 异或运算满足交换律和结合律

这几个特性按照无进位相加的思路来理解,就很好想明白。

3. 异或运算的神奇应用

3.1 两数交换

两个数经过3次异或运算后,可以交换位置。这其实也是上面特性的一个应用。

a=1; b=3;
a=a^b; // a与b异或后,赋值给a:a=1^3 b=3
b=a^b; // 赋值后的a与b再次异或后,赋值给b:a=1^3 b=1^3^3=1(此时a初始的值已经赋给b了)
a=a^b; // 赋值后的a和b再次异或后,赋值给a:a=1^3^1=3 b=1(完成了交换)

以上交换的逻辑,只有在两个数指向不同的内存块时,才有效。如果两个数,指向同一个内存块,实际上就是1个数,此时异或后,会得到0。
算法题:https://leetcode.cn/problems/swap-numbers-lcci/description/

3.2 找到出现奇数次的那个数

有一组数,只有一个数出现了奇数次,其他数都出现了偶数次,如何快速找到这个数?

只要将所有数都做异或运算,得到的结果就是那个数。这是 n^n=0 & 0^n=n 的一个应用。

算法题:https://leetcode.cn/problems/single-number/description/

3.3 提取二进制数最右侧的1(与异或无关)

给定一个二进制的数,找到最右侧的1。例如,二进制数:11001000,最右侧的1对应的二进制数为:00001000。

通过公式:n & (~n + 1) 即可得到结果。

以 11001000 为例:
00110111 // 对n取反:~n
00111000 // 取反后加1:~n + 1
00001000 // 和n进行与运算:n & (~n + 1)

取反运算规则:将二进制的每一位逆转,1变成0,0变成1
与运算规则:仅1&1=1,其他都为0。

应用:找出一个二进制数n中一共有多少个1

rightOne = n & (~n + 1) // 找出最右侧的1
n ^= rightOne // n和rightOne异或后,再赋值给n,可以抹掉n最右侧的1
循环以上两步直到n=0,数出一共循环了多少次即可

算法题:https://leetcode.cn/problems/number-of-1-bits/description/

扩展:通过公式 n & (n - 1) 可以抹掉最右侧的1,也可以找出二进制数中有多少个1。

以 11001000 为例:
11000111 // n - 1
11000000 // n & (n - 1)

3.4 找到出现奇数次的那2个数

有一组数,大部分数都出现了偶数次,只有2个不同的数出现了奇数次,如何快速找到这2个数?

思路:
假设这两个数为a和b,将所有的数进行异或运算,得到的结果一定是:eor=a^b
eor一定不等于0(因为a!=b),也就是说eor的二进制数在某一位上一定是1,且这个1一定来源于a和b其中一个数(因为只有1^0=1)
假设eor在第8位是1,根据第8位是1将数组分成两组,1组中数的第8位都是1,2组中数的第8位都是0,如果a在1组中,那么b一定在2组中
上面两组数中,除了a和b以外,其他数一定出现偶数次。1组所有数全部异或一定等于a,同理2组异或等于b
那么,只要得到eor最右侧的1对应的数eor',再用eor'与最初的数组的每一个数进行与运算,结果等于1(或等于1)的全部保留下来进行异或运算,一定得到了a或b
再用eor异或上面的结果,就得到了另一个数,这样两个数都找到了。

以 [4, 4, 5, 5, 6, 7] 为例(对应的二进制数:[0100, 0100, 0101, 0101, 0110, 0111]):
eor= 4^4 ^ 5^5 ^ 6^7 = 6^7 = 0110^0111 = 0001 // 将所有的数异或
eor'= 0001 // 找到eor最右侧的1对应的数(通过第3.3小节的公式可以得到)
array1= [0100, 0100, 0110] // 分成2组数,这一组和eor'进行与运算后都等于0,其他的数和eor'进行与运算后都不等于0
a= 0100 & 0100 & 0110 = 0110 = 6
b= a^eor = 0110 ^ 0001 = 0111 = 7

算法题:https://leetcode.cn/problems/single-number-iii/description/文章来源地址https://www.toymoban.com/news/detail-844402.html

到了这里,关于异或运算在算法中的神奇应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 异或数列/位运算/数位/二进制

       知识点很多,依次总结: 位运算: 1.左移/右移 针对二进制数位来说的 2.或操作|   与操作   异或操作^ 异或操作满足结合律、交换律和1^x=~x(即x翻转)    0^x=x的规律 3.求数的最高数位: 求得的length为0b100000...其中0的个数等于val化为二进制后的数位值,例如bin(15)=0b1111,为

    2023年04月08日
    浏览(37)
  • 位运算(按位与、按位或、异或、取反)以及原码、反码、补码

    目录 位运算 按位与运算符 [ ] 按位或运算符 [ | ] 异或运算符 [ ^ ] 取反运算符 [ ~ ] 移位操作 一些面试常考的位操作运算 获取二进制中最右边的1 计算机原码、反码、补码 机器数 “三码”之间的转换 计算机中为啥要用补码呢? 真数 原码 反码 补码 有了原码为什么要使用反码

    2024年02月02日
    浏览(50)
  • C语言:位运算符----与(&),或(|),非(~),异或(^),左移(<<)和右移(>>)

    C语言 基础开发----目录 位运算符 就是按二进制位进行运算。 C语言中位运算符主要包括六种,具体如下: 与(),或(|),非(~),异或(^),左移()和右移() 位运算符 含义 说明 按位 与 有0为0,双1为1: 11=1,10=0,01=0,00=0 只有两者对应位都为 1 ,结果对应位才为 1 ,否则为 0 I 按

    2024年01月18日
    浏览(51)
  • C#的几种位操作运算,与、或、非、异或、左移、右移

    C#的常见几种位操作运算,与($)、或(|)、非(~)、异或(^)、左移()、右移() 位操作一般来说比加减乘除计算要快一些 与()操作符的位都为1时,才为1,其他都为0,因此与()操作符的结果范围在[0, Math.Min(x,y)],x,y均为正整数 或(|)操作符的位都为0时,才为0,其他都为1,因此或(|)操作

    2024年02月16日
    浏览(38)
  • 【动态规划】【位运算】1787. 使所有区间的异或结果为零

    【数位dp】【动态规划】【状态压缩】【推荐】1012. 至少有 1 位重复的数字 动态规划汇总 位运算 给你一个整数数组 nums​​​ 和一个整数 k​​​​​ 。区间 [left, right](left = right)的 异或结果 是对下标位于 left 和 right(包括 left 和 right )之间所有元素进行 XOR 运算的结果

    2024年03月17日
    浏览(38)
  • 位运算:按位与、按位或、按位异或、按位左移、按位右移

    目录 一、基础知识补充     (1)位运算     (2)二进制的详细操作 二、位运算     (1)按位与()     (2)按位或(|)     (3)按位异或(^)       (4)按位左移()     (5)按位右移() 三、位运算例题     题目描述:     题解: 四、共勉     位运算符要比一般

    2024年02月03日
    浏览(49)
  • WAF攻防-权限控制&代码免杀&异或运算&变量覆盖&混淆加密&传参

    webshell检测平台 https://scanner.baidu.com/#/pages/intro https://ti.aliyun.com/#/webshell 对比工具代码-菜刀蚁剑冰蝎哥斯拉等 对比WAF规则-函数匹配工具指纹等 1.php 传参带入 ?a=ass x=cGhwaW5mbygpOw== 2.php 变量覆盖 x=cGhwaW5mbygpOw== 3.php 加密变异 http://www.phpjm.net/ 4.php 异或运算 5.php 脚本生成器 Webshel

    2023年04月11日
    浏览(47)
  • 位运算在排序算法中的运用

    异或是如何实现值交换的 异或的性质 满足交换律和结合律 即 a b=b a a b c=a (b c) 且 a^a=0 0^a=a 找出唯一的出现奇数次的数 现有N个数,除了唯一的一个数出现的次数是奇数,其他的均是出现了偶数次的数,现在请编程找出这个出现奇数次的数 找出数组中出现奇数次的两个数 N个

    2024年02月06日
    浏览(31)
  • 什么是预处理器指令,常用的预处理器指令有哪些?什么是运算符,C 语言中的运算符有哪些?

    预处理器指令是一种用于在源代码编译之前进行预处理的特殊指令。它们通过在程序编译之前对源代码进行处理,可以在编译阶段之前进行一些文本替换、条件编译等操作,从而对源代码进行一些宏定义、条件编译等操作。 常用的预处理器指令有以下几种: #define:用于定义

    2024年02月15日
    浏览(55)
  • 探究位运算:位操作在Java中的应用示例

    位运算是计算机科学中的基本概念,它充分利用了二进制表示的特性来进行快速且高效的计算。本文将深入介绍位运算的基础知识,以及在Java中如何应用位操作来解决问题。 概念 :异或(XOR)是一种位运算,用于对二进制数的对应位进行比较。在数字计算中,异或运算有一

    2024年02月11日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包