题目 : a = 5, b = 10, 在不定义新的变量情况下进行两数交换。
相信这道题目很多人都遇到过,如果是定义一个新的变量进行临时存储,大家很快都能做出来。现在我不定义新的变量,使用以下几种方法进行两数交换,然后分析得出最优的方法。
代码1如下:
// 第一种方法, 使用异或运算
public class ExchageNum {
public static void main(String[] args) {
int a = 5;
int b = 10;
// 异或运算
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
}
结果如下图:
代码2如下:
// 第二种方法,使用加减法
public class ExchageNum {
public static void main(String[] args) {
int a = 5;
int b = 10;
// 加减运算
a = a + b;
b = a - b;
a = a - b;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
}
结果如下图:
代码3如下:
public class ExchageNum {
public static void main(String[] args) {
int a = 5;
int b = 10;
// 乘除运算
a = a * b;
b = a / b;
a = a / b;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
}
结果如下图:
方法比较
- 与、或、非、异或运算都属于位运算,而位运算在计算机中执行效率是最高的,在比较简单的运算中可能看不出来位运算与加减乘除运算的执行效率的差距,但是在大数运算中,差距就会比较明显了,如果感兴趣,不妨试一试。
- 此外,第二种方法与第三种方法还涉及数据溢出的问题,因为在Java中,每种基本类型都有其范围,如Integer的范围是-2147483648~2147483647,如果后两种方法的a与b的运算超出该范围,得出的结果毫无疑问是错的,但是位运算不存在这样的问题。
- 综上所述,异或运算方法是最优的,下面说说第一种方法的原理。
交换原理
异或运算原理: 相同为0,不同为1。 如下图
因为是进行位运算,这样不会超出原本数据类型的范围。此外,对称加密就是运用了异或原理。
首先可以将a = 5 当成原文,b = 10 当成密钥,进行异或 ,得到 0111(密文)。然后若想得到原文,只需要将密文和密钥进行异或运算即可。比如,得到密文后,将a当成密钥,与密文进行异或,就可以得到原文b,反之,将b当成密钥,与密文进行异或,就可以得到原文a,就行通过这样的原理进行最终的两数交换。
ps: 如有不足,期待您的指点!