一、异或操作
1、规则:
两个二进制数按位操作,相同为0,不同为1
如110^011 =101
同时可视为二进制无进位加法
2、规律:
1)
0^x =x, 0与其他任何数异或等于其本身,
x^x = 0, 任何数与自身异或结果为0
2)
交换律:a^b = b^a
结合律:(a^b)^c = a^(b^c)
3)
任意n个数异或,先后顺序不影响结果
4)
给一int型数据,找到最右端不为0的那一位 a&(~a+1)
解释:假设a的二进制表示为 101100,取反后为010011,加一010100,二者相与为100,得到最右端的1
二、交换
1、正常交换a,b
temp = a;
a = b;
b =temp;
2、通过位运算交换
a= a^b;//
b= a^b;//此时 b= (a^b)^b=a
a = a^b;//a = (a^b)^a=b
注意:a和b不能是相同内存空间
三、通过异或进行的其他操作
1、给一数组,只有一个数据出现奇数次,其余均为偶数次,找到该数据
public int findOddTimesNum(int []arr){
int res = 0;
for(int a:arr){
res^ = arr;}
return res;
}
2、存在两个出现奇数次的数据
public void findTwoOddTimesNums(int []arr){
int res = 0;
for(int a:arr){
res^=a;
}
//res不为0,证明至少存在一位为1,即两个数有一个该位为1,另一个该位不为1
int ans = 0;
int rightone = res&(~res+1);//找到最右边的1
for(int b:arr){
if(b & rightone==0){//找到该位都为1的,即是其中一个数
ans ^= b;
}
}
System.out.println(ans+" "+(res^ans));
}