异或运算的性质与扩展,以及一道面试题


一、异或运算的性质与扩展

1)无进位相加

1.无论这个数是什么,只要它与零异或,它就会使本身。因为1^0=1 , 0 ^ 0=0; 2.任何数与自己本身想异或结果为零 N^N=0; 3.异或运算可以理解为无进位的相加

2)异或运算的性质

1.N^0=N ;N ^ N =0; 2.满足交换律和结合律 a^b=b ^ a ; a ^ b ^ c = a ^ (b ^ c) 3.无论怎么排列一堆数,他们异或总起来总会是一个数,因为可以用交换律将他们组合成一个异或

3)不用额外变量交换两个数

代码如下:

   int a=3; int b =4;
   a=a^b;
   b=a^b;
   a=a^b;
### 设计的思想

在这里插入图片描述

特别特别注意一定要求交换的两个东西的地址是不同的,值可以一样,但是内存必需不是一个东西。一旦相等就出问题了

4)一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到这一个数

算法设计思路

将数组的所有数值异或到同一个值上
这样,出现偶数次的全部变成零,出现奇数次的就成为剩下的

代码

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

5)一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到这两个数

算法设计思路

首先异或一次得到两个数的异或结果
然后用这个异或结果对数组进行分类
分类的方法,找出一个二进制位为一的位
在这个位上,两个出现奇数次的数字,值必不相同。
然后但独将两个类分别异或,则得到值
也可以用得到的一个值与一开始异或的值进行异或。即可得到该值。

代码

	public static void find2(int [] arr) {
    
    
		
		int eo = 0;
		for(int cur : arr ) {
    
    
			eo ^= cur;
		}
		
		int rone = 0;
		rone = eo &(~eo + 1);
		int a = 0 ,b = 0;
		for(int cur : arr ) {
    
    
			if((cur & rone)==0) {
    
    
				a ^= cur ; 
			}
			b=a^eo;
			
		}
		
	}

Guess you like

Origin blog.csdn.net/weixin_51422230/article/details/121186051