当前位置: 首页 > news >正文

异或运算

异或是一种基于二进制的位运算,用符号XOR或者 ^ 表示,

其运算法则是对运算符两侧数的每一个二进制位,同值取0,异值取1。

它与布尔运算的区别在于,当运算符两侧均为1时,布尔运算的结果为1,异或运算的结果为0。

一、异或的性质

  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

 

二、异或的应用

交换两个数

最常见的做法就是增加一个临时变量,代码如下:

 

  public void switchValue(int a, int b) {
        System.out.println("Before switch:    a:" + a + "\tb:" + b);
        int temp = b;
        b = a;
        a = temp;
        System.out.println("After switch:    a:" + a + "\tb:" + b);
    }

升级版,将两个数加减来实现,代码如下:

   public void switchValue(int a, int b) {
        System.out.println("Before switch:    a:" + a + "\tb:" + b);
        a = a + b;
        b = a - b;
        a = a - b;
        System.out.println("After switch:    a:" + a + "\tb:" + b);
    }

利用异或运算,也可以将两个数交换,例如:

public void switchValue(int a, int b) {
        System.out.println("Before switch:    a:" + a + "\tb:" + b);
        a = a^b;
        b = a^b;
        a = a^b;
        System.out.println("After switch:    a:" + a + "\tb:" + b);
}

 算法题目

 ①1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

解法一:将所有数加起来,减去1+2+...+1000的和。

这个算法已经足够完美了,相信出题者的标准答案也就是这个算法,唯一的问题是,如果数列过大,则可能会导致溢出。
解法二:异或就没有这个问题,并且性能更好。将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数。

解法一很显然,解法二需要证明一下:

前面提到异或具有交换律和结合律,所以1^2^...^n^...^n^...^1000,无论这两个n出现在什么位置,都可以转换成为1^2^...^1000^(n^n)的形式。
其次,对于任何数x,都有x^x=0,x^0=x。
所以1^2^...^n^...^n^...^1000 = 1^2^...^1000^(n^n)= 1^2^...^1000^0 = 1^2^...^1000(即序列中除了n的所有数的异或)。

令,1^2^...^n^..^1000(序列中包含一个n)的结果为T 
则1^2^..^n^..^n^..^1000(序列中包含2个n)的结果就是T^n。 
T^(T^n)=n。
所以,将所有的数全部异或,得到的结果与1^2^3^...^1000的结果进行异或,得到的结果就是重复数。

②一个数组存放若干整数,一个数出现奇数次,其余数均出现偶数次,找出这个出现奇数次的数?

这个其实是①的一个变形题目,最直接的办法还是和上面一样,就是把所有数异或 (奇数个异或是本身,偶数个是0)

Ref: http://www.cnblogs.com/kaituorensheng/archive/2013/04/04/3000033.html

转自http://www.cnblogs.com/yejg1212/archive/2013/04/06/3001060.html

相关文章:

  • 快速枚举因子(约数)
  • 欧拉函数 线性筛法
  • 【条件概率】Headshot, ACM/ICPC NEERC 2009, UVa1636
  • 【数学专题】 卡特兰数
  • 【组合数学】Critical Mass, UVa580
  • 常用算法和数据结构的复杂度速查表
  • 【CodeChef】Just multiply
  • 【CodeChef】LCH15JGH Many bananas
  • 【CodeChef】 Queries on the String
  • 【BZOJ 1051】 受欢迎的牛 【Tarjan】
  • 【数学期望】Crossing Rivers, ACM/ICPC Wuhan 2009, UVa12230
  • 【数学期望】Candy, ACM/ICPC Chengdu 2012, UVa1639 【精度】
  • 【积分】【概率】Probability, UVa11346
  • 【BZOJ 4571】美味 【区间异或最大值】【主席树】【贪心】
  • 【BZOJ 2588】Count on a tree 【树上路径第K大】【LCA+主席树】
  • 【跃迁之路】【585天】程序员高效学习方法论探索系列(实验阶段342-2018.09.13)...
  • Android 控件背景颜色处理
  • angular学习第一篇-----环境搭建
  • CSS相对定位
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • flask接收请求并推入栈
  • Git的一些常用操作
  • IP路由与转发
  • Mocha测试初探
  • PermissionScope Swift4 兼容问题
  • vue脚手架vue-cli
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 检测对象或数组
  • 聊聊directory traversal attack
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 问题之ssh中Host key verification failed的解决
  • 小程序开发之路(一)
  • Java数据解析之JSON
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (07)Hive——窗口函数详解
  • (145)光线追踪距离场柔和阴影
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (二十四)Flask之flask-session组件
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (一)kafka实战——kafka源码编译启动
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)mysql使用Navicat 导出和导入数据库
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .dwp和.webpart的区别
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .Net 知识杂记
  • .NET性能优化(文摘)
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • @SuppressWarnings注解
  • [Angular 基础] - 表单:响应式表单
  • [BUUCTF NewStarCTF 2023 公开赛道] week4 crypto/pwn