两种不需要临时变量的数值交换算法

1. 先上代码:

void swap1(int &a, int &b){
    a ^=b;
    b ^=a;//b=(a^b)^b=a
    a ^=b;//a=(a^b)^a=b
}

void swap2(int& a, int& b)
{
    a+=b;//a=a+b
    b-=a;//b=b-(a+b)=-a
    a+=b;//a=(a+b)+(-a)=b
    b*= -1;//b=a
}

2. 方法说明

方法一:其主要利用了异或运算的如下性质,即:一个数同另一数连续异或2次,可还原为自已,亦 即: a == a ^ b ^ b == b^a^b == b^b^a

该算法利用二进制数(数在计算机就是以二进制的存储的<是补码>)按每一位求异或(两个相同时为0;一个是1,一个是0为1)的一个性质——对任意给定的一个二进制数来说,它与任意一个二进制数,连续异或两次最终得到的还是它本身即有(a = a ^ b ^b)。
证明:因为异或运算是可结合的(满足结合律),且可交换的,所以任何情况一个数和另一个数连续异或都可成 “a ^b ^ b”的形式
再由结合性 a^b^b = a^(b^b) = a^0 = a #
按照这个思想,再结合给出的注释,交换算法就很简单了。

该方法存在的主要问题是:异或算法只能处理整型数据(int,char,long).

方法二:该方法其实主要就是利用了数值运算进行操作。主要查看代码中的注释就可以明白该算法思想,实际上还可以有乘除法的实现方式:

它和加减法类似,但是b!=0。

     a = a * b;

     b = a / b;

     a = a / b;

但是方法二存在的问题是:(1)这种方法可以处理整型和浮点数型,但是处理浮点数的时候,可能会发生精度损失;(2)a=a+b;可能会造成数值过大而溢出。

原文地址:https://www.cnblogs.com/jiayouwyhit/p/3245479.html