异或运算:相同为0,不同为1。(即不进位相加)
异或运算的性质
1)、0^N=N,N^N=0
2)、异或运算满足交换律和结合律
练习一:如何不用额外变量交换两个数(两个数不指向相同的内存地址)
a=a^b;
b=a^b;
a=a^b;
练习二:一个数组中,一个数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这个数
int eor = 0;
int[] arr = new int[]{1, 1, 5, 5, 6, 8, 2, 6, 2, -5, -5};
for (int value : arr) {
eor ^= value;
}
System.out.println(eor);
练习三:怎么把一个int类型的数值,提取出最右侧的1
1)、N & (~N + 1)
2)、jdk中 Integer.lowestOneBit() 也实现这个功能 (N & -N)
练习四:一个数组中,有两个数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两个数
public static void printOddTimesNum(int[] arr) {
int eor = 0;
for (int value : arr) {
eor ^= value;
}
// 只要取出任意一位不同的值即可,此处取出最右侧的1
int rightOne = eor & (~eor + 1);
int onlyOne = 0;
for (int value : arr) {
if ((value & rightOne) == 0) {
onlyOne ^= value;
}
}
System.out.println("第一个数是:" + onlyOne + ",第二个数是:" + (eor ^ onlyOne));
}
练习五:计算一个数字的二进制表示中1的个数
public static void bit1counts(int n) {
int temp = n;
int count = 0;
while (n != 0) {
int rightOne = n & ((~n) + 1);
count++;
n ^= rightOne;
}
System.out.println("数值" + temp + "的二进制表示中1的个数为" + count + "个");
}