异或运算的运用

异或运算

相同为0,不同为1

  • 异或运算的简便记法:无进位相加

异或运算的性质

  • 异或运算满足交换律和结合律,即同一批数的异或结果是一样的
  • 相同两数异或为0

异或运算的几个应用

  1. 不用额外变量交换两个数
// An highlighted block
int a = num1;
int b = num2;

a = a^b; // 此时a = num1^num2
b = a^b; // 此时b = num1^(num2^num2) = num1^0 = num1 = a 
a = a^b; // 此时a = num1^num2^num1 = num2^0 = num2 = b

注意:这种交换操作只能交换处于不同内存空间的两个数,不能交换指向同一空间的两个数

  1. 一个数组中有一个数出现了奇数次,其他数都出现了偶数次,怎么找到这个数
    方法: 令eor=0,然后 target = eor ^ arr[0] ^ arr[1] ^ … ^ arr[n-1]

原理如下:

int arr = [1,1,1,1,2,3,3,4,4,5,5]
// 则target为
int target;
int eor=0;
// 按照上述方法,target=(1^1^1^1)^2^(3^3)^(4^4)^(5^5)=0^2^0^0^0=2
// 这里的原理是异或运算的交换律和结合律,且偶数个相同数异或后为0,奇数个相同数异或后为其本身
  1. 提取int类型数最右侧的1
    假设要提取N最右侧的1,则结果为:N&((~N)+1)

原理如下:
设 N=011011010000
则 ~N=100100101111
(~N)+1=100100110000
N&((~N)+1)=000000010000

  1. 一个数组中两种数出现奇数次,其余数出现偶数次,怎么找到这两个数。
    原理如下:
    在这里插入图片描述
public static void printOddTimesNum2(int[] arr){
	int eor = 0;
	for(int i =0; i < arr.length; i++){
	eor ^= arr[i]
	}
	// eor = a^b
	int rightOne = eor & ((~eor)+1); // 提取eor最右侧的1
	int onlyOnne = 0;
	for(int i =0; i < arr.length; i++){
	if((arr[i] & rightOne) != 0){
		//只异或最右侧为1的数
		onlyOne ^= arr[i];
	}
	}
	System.out.println(onlyOne + " " + (eor ^ onlyOne))
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值