异或运算可以方便记成无进位相加

异或运算的性质:

(1)0^N=N,N^N=0;

(2)异或运算满足交换律和结合律。

异或的运用:

(1)交换两个数

//设有变量a,b,交换a,b两数
a=a^b;
b=a^b;
a=a^b;

异或常见题目:

(1)一个数组中有一个数出现了奇数次,其它数都出现了偶数次,怎么找到并打印出这个数?

//设有满足题意的int型数组arr
int eor=0;
for(i=0;i<arr.length;i++)
{
	eor^=arr[i];
}

(2)怎么把一个int类型的数,提取其最右侧的1出来?

//设有一个int型的数N
//N取反,通过加1就能找到原N右边的第一个1,再与上原N即可
int ANS=N&(~N+1);  

(3)一个数组中有两种数出现了奇数次,其它数都出现了偶数次,怎么找到并打印这两种数?

//设有满足题意的int型数组arr
int eor=0;
for(int i=0;i<arr.length;i++)
{
	eor^=arr[i]; //找到两个目标数a,b的与运算后的结果,存放于eor中
                 //eor必然不为0,即二进制下必有某位i为1
                 //也即目标数a,b中必有a的i为1,b的i为0或反之即反
}
//提取出最右边的1,就以该位为目标位了
int rightOne=eor&(~eor+1);
//eor'
int onlyOne=0;  //用onlyOne来保存目标位为1的那个目标数
//通过判断所有数的目标位是否为1,来将所有数分成两组,a与b必不再同一组
for(int i=0;i<arr.length;i++)
{
	if(arr[i]&rightOne!=0)  //或者arr[i]&rightOne==0
    {
    	onlyOne^=arr[i];
    }
}
cout<<onlyOne<<" "<<onlyOne^eor<<endl;

(4)求一个int型数N中1的个数

//设有int型数N
int count=0;
while(N)
{
	int rightOne=N&(~N+1);  //找到右1
    count++;
    N^=rightOne;  //N异或右1,即减去右1
}