一、按位与运算(&)
按位与"&"功能是参与运算的两数各对应的二进制位与运算。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。
//9的二进制:0000 1001
//5的二进制:0000 0101
//结果为1: 0000 0001
二、按位或运算(|)
按位或"|"功能是参与运算的两数各对应的二进制位或运算。只有对应的两个二进位均为0时,结果位才为0 ,否则为1。参与运算的数以补码方式出现。
//9的二进制:0000 1001
//5的二进制:0000 0101
//结果为13: 0000 1101
三、异或运算(^)
- 满足交换律和结合律
如果a=1,b=2,交换a,b两个数的值。 a=a^b; b=a^b; a=a^b
- 无进制相加
a的二进制表示为 10111
b的二进制表示为 11111
a^b的结果为 01000
题目一
如果一个数组,只有一个数字出现了奇数次,其余的数都出现偶数次,找出这个数
@Test
public void test01(){
int odd = 0;
int[] allArray = {1,2,3,1,1,1,2,3,3};
for (int i = 0; i < allArray.length; i++){
odd = odd ^ allArray[i];
}
System.out.println(odd);
}
//控制台输出
3
题目二
如果一个数组,有两个数字出现了奇数次,其余的数都出现偶数次,找出这个数
分析:
1.出现奇数次的 a^b ≠ 0
2.a^b的结果,二进制中一定有一位是 1。即:如果a的第3位是1,那么b的第三位一定是0
3.把第3位为1的数都进行 异或运算(^),就可以得到 a这个数
4.然后再 a^b^a,就可以得到b
@Test
public void test02(){
int odd = 0;
//4个1,3个2,3个3
int[] allArray = {1,2,1,2,1,2,1,3,3,3};
//计算两个出现奇数次的异或值
for (int i = 0; i < allArray.length; i++){
odd = odd ^ allArray[i];
}
//找到最右边的一个1所在的位置 = 2^n
int oneLocal = odd & (~odd + 1);
int onlyOdd = 0;
for (int i = 0; i < allArray.length; i++){
//一定会存在一个于 oneLocal 相同位是1的数
// 这个数和 oneLocal进行 &运算的时候等于 0
if((oneLocal & allArray[i]) == 0){
//另外一种写法
//if((oneLocal & allArray[i]) != 0){
onlyOdd = onlyOdd ^ allArray[i];
}
}
System.out.println("第一个值为:" + onlyOdd);
System.out.println("第二个值为:" + (odd ^ onlyOdd));
}