不借助變量交換兩個數
我們在平時寫代碼的過程之中,竟然會有交換兩個變量值的需求。然而我們大多數還是會採用藉助額外變量的方式,因爲這種方式不僅簡單,容易理解,可讀性高, 更重要的是適用範圍廣。那麼今天我們來研究一下《如何不借助變量交換兩個數》。
藉助額外的變量
在正式解這道題之前,我們先用最基礎的藉助額外變量的方法來做一下。
JavaScript代碼:
var a = 1;
var b = 2;
var temp = a;
a = b;
b = temp;
這個過程就像交換兩個杯子中的水一樣,如果不借助任何外物,顯然我們不能用常規方法交換兩個杯子的水。
但是問題轉化爲數字就變得有可能了 ,我們來看一下。
利用加法
這是最容易想到的方法,整個過程我畫了一個圖。
JavaScript代碼:
var a = 1;
var b = 2;
b = a + b;
a = b - a;
b = b - a;
但是 a 和 b 的和溢出的風險
,其實我們只要稍加變通一下即可。
我們來看下面的代碼。
利用減法
這個過程我同樣畫了一個圖,可以看出這次沒有出現3了。這在兩個數字都非常大,以至於兩個加起來 無法用數字表示的時候非常有用。
JavaScript代碼:
var a = 1;
var b = 2;
b = a - b;
a = a - b;
b = a + b;
這種解法沒有溢出的風險
,理論上已經非常完美了,難道還有更優的解法麼?
我們來看一種更加高效的做法。
異或
這裏用到了異或這個位運算的性質,即相同則爲 0,不同則爲 1.
於是對於兩個數字,a 和 b。則有 a ^ a ^ b 就等於 b
。我們可以利用這個性質來完成交換。
實際上,有些算法題就可以用這個性質輕鬆解決。
JavaScript代碼:
var a = 1;
var b = 2;
b = a ^ b;
a = a ^ b;
b = a ^ b;
逗號表達式
這個方法來自 大徒弟(@wuyuchang)的方法,這個方法利用了逗號表達式的性質。
什麼是逗號表達式?逗號表達式是將兩個及其以上的式子聯接起來,從左往右逐個計算表達式,整個表達式的值爲最後一個表達式的值。
因此我們可以利用這個性質,先完成一次賦值操作,然後將賦值操作的返回值變爲0. 就可以完成賦值操作
JavaScript代碼::
a = b + ((b = a), 0);
擴展
如果數字非常大怎麼辦?由於數字非常大, 因此我們不能用數字存儲了(也不能用 Bit Int)。我們只能使用別的方式存儲,比如字符串。這個時候我們不能轉化爲數字,然後做四則運算, 那麼我們怎麼辦?
這個其實我們可以自己實現一個“加法”或者“減法”,然後思路就和上面一樣了。關於這部分,可以參考大數相加[1] 和 實現加法[2]