使用三次異或操作交換兩個值

2022-09-11 16:24:30 字數 1256 閱讀 2630

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了 這種情況是很可能發生的 ...