异或看做无进位的相加即可
1010
^
1101
=
0111
基本性质:1满足各种运算律 2 n^n=0 0^n=n
案例1:swap伪代码
//根据我前面的性质2写出来推
a=1,b=2
a=a^b;
b=a^b;
a=a^b;
案例2:两数max方法1(这个方法会有溢出的风险)
// signe的num>>31 & 1:取其符号位
// file的num^1: 1-0 0-1
//为什么?看下面
auto file(int num) { return num ^ 1; }
auto sign(int num) { return file(num >> 31 & 1); } //非负返回1,负数返回0
int main()
{
int a, b; cin >> a >> b; //假设a=3 b=2;
int c = a - b; //c>0->a>b; else……
auto returnA = sign(c); //假设c>0 ,经过上面俩函数,returnA变1
auto returnB = file(returnA); //returnB变0
cout << a * returnA + b * returnB; //然后巧妙的b没了
return 0;
}
案例2:两数max方法2
auto file(int num) { return num ^ 1; }
auto sign(int num) { return file(num >> 31 & 1); }
//强调:非负返回1,负返回0
int sc = sign(c); //c的符号
int sa = sign(a); //a的符号
int sb = sign(b); //b的符号
//两者互斥
int diffAB = sa ^ sb; //判断ab符号是否不一样,不一样返回1,一样返回0
int sameAB = file(diffAB); //判断ab符号是否一样,一样返回1,不一样返回0
//returnA和returnB互斥
int returnA = diffAB * sa + sameAB * sc; //根据上述肯定:加号必有一侧失效
//ab符号不一样,而且sa非负 return a ; ab符号一样而且c(c=a-b)非负 return a returnA不是0就是1
int returnB = file(returnA);
cout << a * returnA + b * returnB;
异或和问题:
1 下标0-10的数组,把数都一起异或起来->异或和
2 把下标异或起来
3 1和2异或,最后就是缺少的1个数字或者很多数字的异或和
int main()
{
vector<int>nums = { 1,3,0,4 };
int a = 0, b = 0;
for (int i = 0; i < nums.size(); i++)
{
a ^= i;
b ^= nums[i];
}
a ^= nums.size();
cout << (a ^ b);
return 0;
}