异或运算

异或运算

异或运算:相同为0,不同为1同或运算:相同以1,不同为0
能长时间记住的概率接近0%

所以,异或运算就记成无进位相加!

性质:

  1. 0^N==N
    N^N == 0
    2)异或运算满足交换律和结合律

题目:如何不用额外变量交换两个数?

首先是两个东西指的内存不一样,和值相等不相等没有关系。

a = a^b;

b = a^b;

a = a^b;

也可以写成:

b = abb;

a = aba;

题目2:—个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数

将所有的数异或起来,偶数次的异或结果是0,其他异或出来的是那个出现奇数词的数组。

//arr中,只有一种数,出现奇数次
	public static void printOddTimesNum1(int[] arr) {
		int eor = arr[0];
		for(int i = 1;i<arr.length;i++) {
			eor ^= arr[i];
		}
		System.out.println(eor);
	}

题目3:怎么把一个int类型的数,提取出最右侧的1来

N&(~N+1)

题目4:—个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数

package day1;

import java.util.ArrayList;
import java.util.List;

//—个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
public class Code8_EvenTimesOddTimes {
	
	//arr中,只有一种数,出现奇数次
	public static void printOddTimesNum1(int[] arr) {
		int eor = arr[0];
		for(int i = 1;i<arr.length;i++) {
			eor ^= arr[i];
		}
		System.out.println(eor);
	}
	//arr中,有两种数,出现奇数次
	public static void printOddTimesNum2(int[] arr) { //笨拙的写法
		/*
		 * a b 不相等
		 * eor不等于0
		 * 说明啊a^b一定有1
		 * 找到某一位是1
		 * 整个数组分成两大类,某一个是1的数,某一位不是1的数,回归上面问题
		 */
		int eor = arr[0];
		for(int i =0; i < arr.length ;i++) {
			eor ^= arr[i];
		}
		//此时的eor就是a^b
		
		int  t =  eor & (~eor+1);
		
		List<Integer> list1 = new ArrayList<Integer>();
		List<Integer> list2 = new ArrayList<Integer>();
		
		//将数组分类
		for(int i = 0; i < arr.length;i++) {
			if((arr[i] & t) == t) {
				list1.add(arr[i]);
			} else {
				list2.add(arr[i]);
			}
		}
		
		int result1 = list1.get(0); 
		int result2 = list2.get(0);
		for(int i = 1 ; i < list1.size();i++) {
			 result1 ^= list1.get(i);
		}
		for(int i = 1 ; i < list2.size();i++) {
			 result2 ^= list2.get(i);
		}
		//获取结果
		System.out.println(result1+"   "+result2);		
	}
	
	public static void printOddTimesNum3(int[] arr) { 
		int eor = arr[0];
		for(int i = 1;i<arr.length;i++) {
			eor ^= arr[i];
		}
		/*
		 * eor = a^b
		 * eor != 0
		 * eor 必然有一个位置上是1
		 */
		int rightOne = eor &(~eor+1);  //提取出最右侧的1
		int onlyOne = 0; // 再遍历一遍
		for(int i = 0 ;i<arr.length;i++) {
			if((arr[i] & rightOne) != 0) { //等同于 = rightOne
				onlyOne ^= arr[i];
			}
		}
		System.out.println(onlyOne+"    "+(eor ^ onlyOne));
			
	}
		
	
	public static void main(String[] args) {
		int[] arr = {3,3,2,3,1,1,1,3,1,1,1};
		printOddTimesNum1(arr);
		int[] arr2 = {4,3,4,2,2,2,4,1,1,1,3,3,1,1,1,4,2,2};
		printOddTimesNum2(arr2); 		
	}	
	
}

题目5:取出二进制1的个数

package day1;
//获取二进制中1的个数
public class Code9_Get1In0101 {
	
	public static int bit1counts(int n) {
		int count = 0;
			int rightOne = n & (~n +1);
		while(n != 0) {
			count++;
			n ^= rightOne;	
		}
		return count; 
	}
	
	public static void main(String[] args) {
		System.out.println(bit1counts(13));		
	}
}
posted @ 2021-06-20 20:31  IT小五  阅读(426)  评论(0)    收藏  举报