博客
关于我
左神算法班笔记——异或
阅读量:279 次
发布时间:2019-03-01

本文共 1639 字,大约阅读时间需要 5 分钟。

异或

异或即相同为0,不同为1(也可以看作无进位的二进制加法

0^0==0;0^1==1;1^0==1;1^1==1;

异或特点:

1.满足交换律:a^b^c==a^c^b;2.0^a==a;3.a^a==0;
例题

现在有一个数组a,

(1)里面有1种数出现了奇数次,其他数都出现了偶数次,求这个出现了奇数次的数。

解题思路

由异或的性质可知,同一种数自己异或自己偶数次,结果是0;同一种数自己异或自己奇数次,结果是还是它自己。所以,我们可以把这个数组中所有的数都异或到一起,出现了偶数次的数异或后为0,出现的奇数次的数异或后是它自己,这样结果就是那个出现了奇数次的数。

代码:

public static void printOddTimeNum1(int[] arr) {           int eor = 0;        for(int cur : arr) {               eor ^= cur;        }        System.out.println(eor);    }

(2)里面有2种数出现了奇数次,其他数都出现了偶数次,求这2个出现了奇数次的数。

解题思路:

因为是2种数,所以a^b != 0而且 a^b 必有一个二进制位上是1。所以,我们把这个数组分为该位 是1 和 是0 两组数,然后所有该位是1的数异或到一起,结果就是a或b其中一个。(因为其他数的出现的次数为偶数)将该结果再与a^b异或,就能得到另一个数。

代码:

public static void printOddTimeNum2(int[] arr) {           int eor = 0,onlyOne = 0;        for (int curNum : arr) {               eor ^= curNum;        }        // eor = a^b        // eor != 0        // eor的二进制必有一个位是1(因为a != b,所以必有一位不同)        int rightOne = eor & (~eor + 1);//取出eor最右边的1        for(int cur : arr) {               if((cur & rightOne)==0) {   //只和那一位不是1的那一类数异或                onlyOne ^= cur;            }            //onlyOne 为a或b其中一个;onlyOne^eor为另一个        }        System.out.println(onlyOne+" "+(onlyOne^eor));    }

代码具体解析:

int rightOne = eor & (~eor + 1);rightOne 的唯一一位1与a^b最右边的第一个1位置相同,而且rightOne的其他位都是0原理:(假设a^b为110010100)a^b     		110010100~a^b    		001101011//取反~a^b+1  		001101100//加1(a^b)&(~a^b+1)  000000100// 这就是rightOne/for(int cur : arr) {               if((cur & rightOne)==0) {                   onlyOne ^= cur;            }            //onlyOne 为a或b其中一个;onlyOne^eor为另一个        }这样,和rightOne进行&操作后结果 为0 的数是一类,结果 不为0 的数是一类,而a、b分别在这两类中的一类。所以我们把同一类中的数异或到一起,就能求出a或b。

转载地址:http://icsa.baihongyu.com/

你可能感兴趣的文章
Netty工作笔记0075---handler链调用机制实例1
查看>>
Netty工作笔记0076---handler链调用机制实例3
查看>>
Netty工作笔记0077---handler链调用机制实例4
查看>>
Netty工作笔记0078---Netty其他常用编解码器
查看>>
Netty工作笔记0079---Log4j整合到Netty
查看>>
Netty工作笔记0080---编解码器和处理器链梳理
查看>>
Netty工作笔记0081---编解码器和处理器链梳理
查看>>
Netty工作笔记0082---TCP粘包拆包实例演示
查看>>
Netty工作笔记0083---通过自定义协议解决粘包拆包问题1
查看>>
Netty工作笔记0084---通过自定义协议解决粘包拆包问题2
查看>>
Netty工作笔记0085---TCP粘包拆包内容梳理
查看>>
Netty常用组件一
查看>>
Netty常见组件二
查看>>
Netty应用实例
查看>>
netty底层——nio知识点 ByteBuffer+Channel+Selector
查看>>
netty底层源码探究:启动流程;EventLoop中的selector、线程、任务队列;监听处理accept、read事件流程;
查看>>
Netty心跳检测
查看>>
Netty心跳检测机制
查看>>
netty既做服务端又做客户端_网易新闻客户端广告怎么做
查看>>
netty时间轮
查看>>