异或运算详解与练习

Posted 飞人01_01

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异或运算详解与练习相关的知识,希望对你有一定的参考价值。

一、异或运算讲解

按位异或 / 同或

int main()
{
	//按二进制位展开
	//按位异或: 相同为0,不同为1
	//按位同或: 相同为1,不同为0
	int a = 10;  //二进制: 0000 1010
	int b = 6;   //二进制: 0000 0110
	int c = a ^ b; //     0000 1100
	return 0;
}

同或相对来说,在面试中不会遇到,主要就是异或。两者的功能是相反的,容易记混淆,这里提供一个简单的记忆方法 :

异或:按二进制位展开做加法不进位运算。”

例如: 上述代码:0000 1010 和 0000 0110 分别对应相加:
在这里插入图片描述

蓝色字体本应是 1 + 1 = 2,理应来说需要往高位进1,这里异或,则不进,直接余0即可。 其他 非蓝色字体 按照正常的加法运算后,写下来即可。

异或性质(重点):

  1. n ^ 0 = n
  2. n ^ n = 0

二、练习题

题目链接
计算数组中出现奇数次的数值牛客网
二进制中1的个数牛客网

计算数组中出现奇数次的数值

在这里插入图片描述

//例如数组:  [3,2,3,3,2,2,2,5,7,9,7,5,9]
//数值3有3个,2有4个,   5、7、9 各有2个

如果这题直接暴力排序求解的话,就违背了面试官的初衷,也就是说这次面试凉了一大截了。

那么如何赢得面试官的青睐呢?不急往下看。

我们说了上面的异或性质,该怎么用呢。

想想,此题中出现的所有数据中,只有一个数据是出现了奇数次,其他的都是偶数次,那我们把所有的数据进行一个异或,最后异或的结果不就是那个奇数次的数值嘛。
注释: eor = 3 ^ 3 ^ 3 ^ 2 ^ 2 ^ 2 ^ 2 ^ 5 ^ 5 ^ 7 ^ 7 ^ 9 ^ 9 ;
划横线部分可以用 异或性质2 计算出 这一串都是0,化简为 eor = 3 ^ 3 ^ 3 ^ 0; 前面的 两个 3异或运算 后得到0 ,即就是说最后的式子化简为 eor = 3 ^ 0; 到了这一步不就是 异或性质1 吗? 最终结果就是 3 咯。

 public static void main(String[] args) {
        int[] arr = {3,2,3,3,2,2,2,5,7,9,7,5,9};
        int eor = 0;
        for (int i = 0; i < arr.length; i++) {
            eor ^= arr[i];
        }
        System.out.println("eor: " + eor);
    }

二进制中1的个数

在这里插入图片描述
按照常规的取模运算,这样的解题思路,是入不了面试官的眼的。只能换个思路解。还是位运算的角度求解。

直接上代码。

解法一:异或

    public static void main(String[] args) {
        int a = 10;
        int count = 0;
        while (a != 0) {
            count++;
            a = a ^ (a & ((~a) + 1));
            //a & ((~a) + 1) 计算得到的是a二进制位中最右边的1 
        }
        System.out.println("count: " + count);
    }

这里特别需要讲解一下的就是这个 a & ((~a) + 1)
在这里插入图片描述
这样,我们就可以拿到10这个数在内存中最右边的 1 ;

最后再与a本身做 异或运算 ,就 ***“约”***掉了最右边的1;

这个算法思想a & ((~a) + 1),在以后刷题中,会应用到很多场景,各位小阔爱得深刻理解里面的奥妙哦。

解法二:与运算

   public static void main(String[] args) {
        int a = 10;
        int count = 0;
        while (a != 0) {
             count++;
             a = a & (a - 1);
        }
        System.out.println("count: " + count);
    }

具体的算法思想,就留给大家自己动手画一画吧。

本期更新到此结束,如若觉得小编写的还可以,能够学到一些知识,还请点个赞哦,在此感谢啦!!!

下期见!!!
在这里插入图片描述

以上是关于异或运算详解与练习的主要内容,如果未能解决你的问题,请参考以下文章

Java的位运算符详解实例——与(&)非(~)或(|)异或(^)

Java的位运算符详解实例——与(&)非(~)或(|)异或(^)(仅作记录)

《算法零基础100讲》(第46讲) 位运算 (异或) 入门

史上最通俗易懂的异或运算详解含例题及应用

Java的位运算符详解实例

《算法零基础100讲》(第47讲) 位运算 (异或) 进阶