关于异或运算

异或运算

1.异或概念

XOR 是更单纯的 OR 运算。

我们知道,OR 运算的运算子有两种情况,计算结果为true。

(1)一个为 true,另一个为 false;

(2)两个都为 true。

上面两种情况,有时候需要明确区分,所以引入了 XOR。

XOR 排除了第二种情况,只有第一种情况(一个运算子为true,另一个为false)才会返回 true,所以可以看成是更单纯的 OR 运算。也就是说, XOR 主要用来判断两个值是否不同。

或运算维恩图
图一:或

异或运算维恩图
图二:异或

可以有以下情况
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
(相同的时候为0,不同为1)

2.C语言中异或运算

在C中异或用^表示(如a ^ b)一般作用于整数数据之间
int a=6;
int b=3;
则a^b
(00000110)^(00000011)=00000101(5)

他有以下运算规律
1.一个值与自身的运算,总是为 false。

  • x ^ x = 0

2.一个值与 0 的运算,总是等于其本身。

  • x ^ 0 = x

在这里插入图片描述
3.可交换性
x ^ y = y ^ x

4.结合性
x ^ (y ^ z) = (x ^ y) ^ z

在这里插入图片描述
可以看到三个数运算时,如果这一位上三个之中只有一个0时,不管在什么位置结果都为0
其他结果为1
所以计算与顺序无关

3.异或运算的运用

1.交换值

(利用结合性和交换性)

void swap(int *x, int *y) {
    if (*x != *y) {
        *x = *x ^ *y;
        *y = *x ^ *y;//*y=*x^*y^*y=*x
        *x = *x ^ *y;//*x=*x^*y^*x=*y
    }
}


2.处理数组中有关重复的问题

(利用结合性和交换性)

如:查找数组唯一值
问题:数组中只有一个元素是不重复的,其他的都有重复的元素
原理:a[1]^ a[2] ^ a[3] ^a[4]…利用异或的运算性质相同的先算变为0,一个值与 0 的运算,总是等于其本身,最后只剩下数组中不重复的数
int arr[] = {1, 1, 2, 2, 3, 4, 4, 5}

int fun(int* p,int numSize){
	int a=0;
	for(int i=0;i<numSize;i++)
		a^=p[i];
	
	return a;

}
int arr[] = {1, 1, 2, 2, 3, 4, 4, 5};
numSize=sizeof(arr)/sizeof(int);
int a=fun(arr,numSize);

如:一个数组包含 n+1 个成员,这些成员是 1 到 n 之间的整数。只有一个成员出现了两次,其他成员都只出现一次,请找出重复出现的那个数字。

int fun(int* p,int numSize){
	int a=0;
	for(int i=0;i<numSize;i++)
		a^=i;
		a^=p[i];
	//1^2^3....^n^a[1]^a[2]^a[3]....^a[n]          总长度n+1的数组
	return a;
int arr[] = {1, 6, 2, 3, 6, 4, 5};
	//只有一个元素进行了三次本身的运算6^6^6=6 其他对本身两次运算3^3=0
3.数据备份

不难发现,若
z=x^y;对两边同时 ^y ,z ^y=x ^y ^y=x,得x=z ^y
同理两边^x即可得到y=z ^x

故可以 使用异或也可以很容易实现多个数据的互相备份,假如有数据a、b、c,则d = a ^ b ^ c,然后把数据d备份下来。

当a丢失时,可使用d ^ b ^ c来恢复
当b丢失时,可使用d ^ a ^ c来恢复
当c丢失时,可使用d ^ a ^ b来恢复

4.加解密

(利用结合性)

比如明文数据是message,密钥是key,加密后的数据是secret,确保通信发送方和通信接收方都存储了相同的key,key可以使用rand()生产一串随机数,则举例说明:
// 加密
secret = message ^ key
0x2C0E = 0x89AB ^ 0xA5A5
// 解密
message = secret ^ key
0x89AB = 0x2C0E ^ 0xA5A5

原理
(x ^ y) ^ y
= x ^ (y ^ y)
= x ^ 0
= x

这里是引用
异或运算 XOR 教程
https://www.ruanyifeng.com/blog/2021/01/_xor.html
浅谈C语言中异或运算符的10种妙用
https://blog.csdn.net/helloqusheng/article/details/137889847

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值