在程式中實現交換兩個數的功能並不複雜,但如果不使用中間變數,就需要動一下腦筋。本文介紹了兩個方法 (其實原理都是一個)。其基本原理就是數的中和。也就是說,透過某種運算 (二元運算) 將 a 和 b 兩個數變成一個數,並保存在其中一個變數中。然後再透過同樣的運算符將 a 或 b 中和掉。這樣實際上是利用了 a 或 b 本身作為了中間變數。
static class Num { int a; int b; }
public static void swap1(Num num) {
num.a = num.a + num.b;
num.b = num.a - num.b;
num.a = num.a - num.b;
}
上面程式碼透過 + 運算子將 a 和 b 的運算結果賦給了 a (此時 a 是中間變數)。然後再計算 b,此時 a 的值已經是 (a+b) 了,因此 a 再減 b 就是原來的 a。而此時 b 已經是原來的 a 了,因此再用運算後的 a (實際上是 a+b) 減運算後的 b (實際上是原來的 a),就是原來的 b 了,最後將這個 b 賦值給 a。
實際上,我們還可以使用 *、/ 等符號來實現同樣的效果,程式碼如下:
public static void swap2(Num num) {
num.a = num.a * num.b;
num.b = num.a / num.b;
num.a = num.a / num.b;
}
public static void swap3(Num num) {
num.a = num.a - num.b;
num.b = num.a + num.b;
num.a = num.b - num.a;
}
上面程式碼在 Java 中沒有什麼問題 (但使用 / 時,分母和分子不能為 0)。就算溢位也會得到正確的結果,但有某些語言中 (如 C 語言),可能會拋出溢位錯誤。為了避免這種錯誤,可以加判斷,程式碼如下:
public static void swap4(Num num) {
// 不同號
if (num.a * num.b <= 0) {
num.a = num.a + num.b;
num.b = num.a - num.b;
num.a = num.a - num.b;
} else {
num.a = num.a - num.b;
num.b = num.a + num.b;
num.a = num.b - num.a;
}
}
當然,我們還有更好的方法,就是使用異或運算子 (^)。我們知道,任何數與 0 異或後仍然為它本身,兩個相同的數異或後為 0。基於這種特性,可以有如下程式碼。
public static void swap5(Num num) {
num.a = num.a ^ num.b;
num.b = num.a ^ num.b;
num.a = num.a ^ num.b;
}
異或交換法不僅避免了溢位風險,也適用於整數類型,是交換兩數值的經典技巧。