异或运算
异或运算
异或运算:相同为0,不同为1同或运算:相同以1,不同为0
能长时间记住的概率接近0%
所以,异或运算就记成无进位相加!
性质:
- 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));
}
}