已知在一个数组中:只有一种数出现了奇数次,其他的都是偶数次;有两种数出现了奇数次,其他都是偶数次。求这一种数和两个数。


异或运算总结


今天我们一起来聊聊异或运算:

定义:

异或,是一个数学运算符,英文为exclusive OR,缩写为xor,应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。

异或也可以看成是不带进位的加法,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。

异或运算的作用

1.参与运算的两个值,如果两个相应bit位相同,则结果为0,否则为1。

即:

0^0 = 0,

1^0 = 1,

0^1 = 1,

1^1 = 0
2.使用异或交换两个数,在冒泡排序、选择排序等众多的排序算法中,都会涉及到两个数值的交换,一般做法是利用空间,这样的话,效率就会大大的降低,使用异或可以解决空间问题。但是需要注意的是:使用亦或操作必须要保证的是内存地址不能相同,如果某一个数组有相同的指向,那么亦或完了之后所得结果会是0。

a = int[a] ^ int[b]
b = int[a] ^ int[b]
a = int[a] ^ int[b]

3.面试题:已知在一个数组中:只有一种数出现了奇数次,其他的都是偶数次;有两种数出现了奇数次,其他都是偶数次。分别找到这个数以及这两个数。

分析思路:其实第一问是很好想到的,对数组中所有的数都进行亦或操作,由于除了这个数的其它数都是偶数个,那么由于亦或操作的结合律(亦或操作还具有交换律),所有的偶数所得结果为0,那么此时就是0^这个数,最终就是所求的数。具体代码:

public static void printOneNums(int[] nums){
	int xor = 0;
	for (int num : nums) {
		xor ^= num;
	}
	System.out.println(xor);
}

第二问:所有的数异或得到所求的两个数a^b,又知道a!=b,那么必然有一位上不是0,(可以求最右边的为1的数:rigthOne = xor & (~xor + 1))(原因在下面),设变量xor1 ,让数组中所有那一位为0或者为1的数进行异或运算,得到的就是a或者b,那么另一个数字就是xor^xor1。
在这里插入图片描述

    public static void printNum2(int[] nums){
        int xor = 0;
        for(int num: nums) {
            xor ^= num;
        }
        int rirhtOne = xor & (~xor + 1);//找到最右边为1的数
        int xor1 = 0;
        for(int cur: nums){
            if((cur & rirhtOne) == 1){ //筛选出那一位上为1或者0的数
                xor1 ^= cur;
            }
        }
        System.out.print("第一个数:"+xor1+",第二个数:"+ (xor ^ xor1));
    }
}

结尾:
纯属记录自己的学习过程,如果有错误,欢迎指出,一起进步。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值