三次异或交换两个值

三次异或交换两个值

a = a ^ b;
b = a ^ b;
a = a ^ b;

1. 数值交换的本质

由于变量a和变量b在内存中实际上是以二进制存储的,即

/* a在内存中的二进制值为 0010 0010 */
char a = 34;
char b = 28;
/* b在内存中的二进制值为 0001 1100 */

我们想交换ab的值,本质上是交换两者在内存中的二进制值。也就是将对应的每一个二进制位都进行交换。在这个交换的过程中,如果待交换的位相同,那么交换和不交换的结果一致;如果待交换的位不同,那么交换完后0变成了11变成了0,二进制表示法中,只有01两个数字,所以交换也可以理解为取反。概括而言,相同的位不变,不相同的位取反

因此交换的步骤可以拆分为:首先寻找两个数的二进制值中相同和不同的位置,相同的位置二进制值不变,不相同的位置二进制值取反(1取反就是00取反就是1),这样就达到了交换的目的。举个例子,还是上面的ab

bit7bit6bit5bit4bit3bit2bit1bit0十进制值
a0010001034
b0001110028
相同相同不同不同不同不同不同相同

按照相同的位不变,不相同的位取反的规则操作后:

bit7bit6bit5bit4bit3bit2bit1bit0十进制值
a0001110028
b0010001034

可见,经过这一番操作后,两个数交换了。这样的操作有一个前提:知道哪些位相同,哪些位不相同。也就是说,如果能得到一个对照表cc中存储了ab哪些位相同哪些位不同的信息,那么就可以利用相同的位不变,不相同的位取反的规则进行交换数据了,这一规则可以用异或运算来实现。

2. 异或的特性

xor异或,一种二进制位运算,不同为1,相同为0。

当相应位和0异或时,假设自身为1,则1^0=1,也就是自身的值不变;假设自身为0,则0^0=0,自身的值还是不变——得出结论1:

与0异或,自身不变

当相应位和1异或时,假设自身为0,则0^1=1,也就是自身的值取反;假设自身为1,则1^1=0,自身的值还是取反——得出结论2:

与1异或,自身取反

那么,只要对照表c中,相同的位用0表示,不同的位用1表示,ac异或就能实现相同的位不变,不相同的位取反bc异或也能实现相同的位不变,不相同的位取反,两个数就交换了。

3. 三次异或交换的解释

第一次异或:a = a ^ b

为了便于阐述,我们令c=a^b(其实就是第一次异或操作完的a),注意观察c中的每一位,0对应着相同,1对应着不同,完美实现了对照表的功能。也就是说,第一次异或操作得到了一个对照表c

bit7bit6bit5bit4bit3bit2bit1bit0十进制值
a0010001034
b0001110028
相同相同不同不同不同不同不同相同
a^b00111110

第二次异或:b=b^a

此时与b进行异或操作的a,已经不是原始的a了,经过第一步异或操作后,原始a的值已经被改变成c,因此我们可以将b=b^a理解为b=b^c,即原始的**b和对照表进行异或**,这样一来=左边的b的值就变成了原始a的值。

第三次异或:a=a^b

=号右边的ab此时都已不是原始的ab了,此时的a实际上是对照表cb实际上是原始的a,如此一来,=右边的a^b就可以解释为原始的a和对照表进行异或操作,显然,这样得到的结果是原始的b

4. 结论

a = a ^ b;	/*        得到对照表        */
b = a ^ b;	/* 原始b和对照表异或得到原始a */
a = a ^ b;	/* 原始a和对照表异或得到原始b */
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值