a和b是兩個ascii碼表中的可列印字元,經過以下三次異或操作,可以達到交換目的:
a ^= b;
b ^= a;
a ^= b;
首先要理解,什麼是^(異或)操作:
二進位制兩數運算結果:
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
相同為0,不同為1
因為ascii碼表中的字元都有對應十進位制的值
假設:a = 10 , 其二進位制數為: 1010
b = 12 , 其二進位制數為: 1100
如果a和b交換,在二進位制數看來,因為第一位和最後一位數相同,所以中間兩位數只要交換一下就行了
這個交換的過程,因為二制進中只有兩個數值(0和1),所以實際上只是0變1,1變0
所以總結出來就是,交換兩個數,就是它們的二進位制數不一樣的位數,只要各自取反(0變1,1變0)就行了
如果兩個數轉換為二進位制數的位數不一樣,只要短的那個前面補0即可。
第一次 a = a ^ b
其結果a的值為: 0110,去掉前面的0,即110,仔細觀察,此時的a其實是乙個差異值(位數上的值是1的表示有差異),它找到了原來a和b的二進位制數不相同的位數,1表示不相同,0表示相同
110表示,原來a和b在二進位制裡中間兩位數是不一樣的,這樣就找到了在二進位制中哪些位數是a和b不相同的。
第二次 b = a ^ b
此時a是乙個差異值,b還是原來的數,它是如何變成a的原值呢
異或運算可以從另乙個角度去理解:
當左邊的數為0時,其結果就和右邊的數一樣
當左邊的數為1時,其結果就和右邊的數取反
所以此時的a ^ b就是:
左邊的a,如果位數為0,表示原值a和b的這個位數是一樣的,那麼b的這個位數就不需要改
左邊的a,如果位數為1,表示原值a和b的這個位數是不一樣的,那麼b的這個位數就需要取反
所以b原來的值1100,前後兩位數不變,中間兩位數取反,其結果就是1010,這就符合上面交換兩個數的結論。
第三次 a = a ^ b
此時a還是差異值110,b已經變成原來a的值了,那麼a ^ b還是像上面那樣,對於b(現在已經是原來a的值),相同的位數不變,不同的位數取反,其結果就是原來b的值。
簡單結論:
異或操作找出二進位制數不相同的位數,然後各自取反。
使用異或運算交換兩個變數的危險
我們知道,在排序演算法中經常會需要交換序列中的兩個變數,常見有兩種方法 1.借助第三個臨時變數 交換 int temp array i array i array index array index temp 2.借助異或運算的特性 array i array i array index array...
演算法《異或操作交換兩個數的坑》
private static void swaptwonum int a,int i,int j 很多人都習慣使用了異或操作 public class test1 swaptwonum nums,0,0 自身和自身交換 private static void swaptwonum int a,int...
用異或交換兩個整數的陷阱
前面我們談到了,可用通過異或運算交換兩個數,而不需要任何的中間變數。如下面 void exchange int a,int b 然而,這裡面卻存在著乙個非常隱蔽的陷阱。通常我們在對陣列進行操作的時候,會交換陣列中的兩個元素,如exchang a i b j 這兒如果i j了 這種情況是很可能發生的 ...