异或:如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。(同假异真)
在C语言中a^b表示a和b进行按位异或即
例a=3,b=5,c=a^b;
a=011;
b=101;
c=110;即c=6
根据异或规则可推出以下定理:
①一个数异或上自己等于0,即a^a=0,3^3=0,5^5=0......
②任何一个数与0异或还等于其本身,3^0=011⊕000=011=3,5^0=110⊕000=110=5......
③异或满足交换律:3^5^3=011⊕101⊕011=110⊕011=101=5
3^3^5=011⊕011⊕101=000⊕101=101=5
应用以上规则可以求解某些题目:
例一:交换两个int变量的值,不能使用第三个变量,即a=3,b=5,交换之后a=5,b=3。
解法一:
int a=3;
int b=5;
a=a+b;//a现在存的是a和b的值
b=a-b;//a+b减去b=a(b存a)
a=a-b;//和减去b(存的a值)即为b
交换完成(可能存在溢出问题)
解法二:根据异或规则:
a=a^b;
b=a^b;(a^b^b=^a=a)
a=a^b;(a^b^a=a^a^b=^b=b);
例二:给出一个非空整形数组,除了某些元素只出现一次以外,其余每个元素均出现两次,找出那个只出现一次的元素.
样例:int a[]={1,2,3,4,5,1,2,3,4}该数组只有5出现一次,其他数字都是成对出现的,要找出5.
解法一:暴力算法
#include<stdio.h>
int main()
{
int a[] = { 1,2,3,4,5,1,2,3,4 };
int sz = 0;
int count = 0;
sz = sizeof(a)/sizeof(a[0]);
int i, j;
for (i = 0; i < sz; i++)
{
count = 0;
for (j = 0; j < sz; j++)
{
if (a[i] == a[j])
{
count++;
}
}
if (count == 1)
{
printf("singel dog:%d\n", a[i]);
break;
}
}
return 0;
}
解法二:题目给出其他元素出现两次,可以根据规则a^a=0,0^a=a;
给出算法
#include<stdio.h>
int main()
{
int a[] = { 1,2,3,4,5,1,2,3,4};
int sz = 0;
int result = 0;
sz = sizeof(a)/sizeof(a[0]);
int i;
for (i = 0; i < sz; i++)
{
result = a[i] ^ result;
}
printf("singel dog:%d\n", result);
return 0;
}