在计算机中,如果想要交换变量的值:
Demo1:
常规的算法是
public static void doSwitch(int a,int b){ int temp = a; a = b; b = temp; System.out.println("a:"+a+"b:"+b); }
但是这种方式需要通过第三方变量,
Demo2:
于是又有了第二种算法,
public static void doSwitch2(int a,int b){ a = a+b; //a存入两者之和 b = a-b;//两者之和减去b的值就是a的值,此时,b存入了a的值 a = a-b;//两者值和减去b(a的值),就是b的值 System.out.println("a:"+a+"b:"+b); }这种算法的思想是先把a+b的和储存在a中,那么 减去b的值则获得a的值,减去a的值则获得b的值。
但是这种算法有可能会出现数值溢出的情况(两个int值相加有可能大于Integer.MAX_VALUE)
Demo3
于是有了第三种算法
public static void doSwitch3(int a,int b){ if (a>b){ a = a-b; //a存入两者之差,确保正值 b = b+a;//因为a大b小,则b加上两者之差,为a的值 a = b-a;//a的值减去两者之差,为b的值 } else{ a = b-a;//存下两者之差 b = b-a;//b大a小,b减去两者之差就是a的值 a = a+b;//两者之差加上a的值就是b的值; } System.out.println("a:"+a+"b:"+b); } 这种算法先判断下a,b两个值的大小,用大的减去小的, 确保不溢出,同时存下a-b之差,然后通过差来运算 这种算法明显优于前面两种算法,没有用到第三方变量,也没有溢出的问题。 但是不足之处是使用了if判断,代码量是前两个的两倍。Demo4
于是有了更好的算法
在介绍之前,先介绍一个概念
位运算:
我们知道,计算机中的数据实际上都是0101,
而位运算其实就是对0101的直接运算。
位运算包含多种运算符,其中一种叫做异或,
在java中用^表示,异或的运算规则为:
如果两个值相同,则运算结果为1,否则为0
如果从单个位上来看,异或运算包含四种情况。
0^1 ==》1
0^0 ==》0
1^1 ==》0
1^0 ==》1
如果我们把上面的运算再算一次,会怎么样呢?
0^1 ==》1 1^1 ==》0
0^0 ==》0 0^0 ==》0
1^1 ==》0 0^1 ==》1
1^0 ==》1 1^0 ==》1
可以看出,异或对同一个值进行两次运算后,其结果为原来的值
同时,我们可以很明显的看出,异或运算满足交换律,a^b = b^a
继续:
Demo5
于是我们尝试使用异或来进行变量值的交换
public static void doSwitch(int a,int b){ a = a ^ b;//a和b的异或状态储存到a中 b = a ^ b;// 继续异或b则得到a的值 a = a ^ b;//ab之异或后再异或b(a的值)则得到b的值 System.out.println("a:"+a+"b:"+b); }
可以看出,最后一种算法,
既没有使用第三个变量,
也没有溢出问题,代码量也不大。