不使用暫存變數交換兩個變數
題目
不使用暫存變數交換兩個變數。
Swap two variables without using a temporary variable.
解法
常見的方法有以下方式:
加減法
1 | a = a + b |
乘除法
1 | a = a * b |
XOR 法
1 | a = a ^ b |
由於使用加減乘除有可能會有溢位 (overflow) 的問題,所以最好的方式是使用位元運算的 XOR。
說明
加減乘除我們用數學角度來看很好理解,以加減為例:
1 | 假設 X、Y 和 Z 為未知數,a 和 b 為已知數,已知: |
X 代入第二式
1 | Y = (a + b) - b = a |
接著將 X 和 Y 代入 Z,可得
1 | Z = (a + b) - a = b |
回頭和程式對比,可以發現 Y 相當於 b 變數,Z 相當於 a 變數。
使用位元運算並不好去理解為什麼這樣子做就可以達到交換的目的,首先要瞭解以下三點:
- XOR 定義:有且僅有一個為真,換句話說就是,相同的為 0,不同的為 1。
- N ^ N 為 0:有了以上的定義,我們假設一變數 N,當 N ^ N 的時候,由於每個位元必定相同,所以結果一定是 0。
- N ^ 0 為 N:而 N ^ 0 的時候,只有在位元是 1 的地方會不同,所以結果就是 N 本身。
當有了以上三點條件之後,我們再列出數學命題:
1 | 假設 X、Y 和 Z 為未知數,a 和 b 為已知數,已知: |
我們可以將 X 代入第二式,並依據前面所提到的三點條件,可得知
1 | Y = (a ^ b) ^ b = a ^ b ^ b = a ^ (b ^ b) = a ^ 0 = a |
接著將 X 和 Y 代入 Z,可得
1 | Z = (a ^ b) ^ a = a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b |
將以上推導對照程式的 XOR 法就能理解交換之原理,當然也可以直接背起來就好。
延伸閱讀
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 小殘的程式光廊!
Comment