交換兩個變數,有很多種方法,就不一一介紹了.
大多數人首先能想到的方法是定義一個臨時變數,
如下:
int a = 5;
int b = 10;
int temp = a;
a = b;
b = temp;
此結果就是a = 10,b = 5;
這種方法雖然使用到一個臨時變數,性能上可能稍微弱了一點點(達不到顯著水平),但是交換資料很安全,可讀性也非常高,推薦使用這種方法.
然而一些喜歡體現自己是技術大神的同學,喜歡使用異或進行交換,如下:
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
此時的結果 a = 20; b = 10;
這個方法使用了異或的特性,本身不會有什么問題,由于操作的是二進制進行運算,也沒有定義新的變數,理論上性能會高一些,
當然,還可以裝大神,顯示自己技術大牛,然而它也是有缺陷的,可讀性就比較差.
寫到這里,異或的方法如果僅僅是可讀性差,那么也沒必要說它有什么陷阱了.可是真的是這樣的嗎?
這里的陷阱還需要從選擇排序說起.
我們都知道,選擇排序的底層實作是這樣的:
public static void sort(int[] arr){
for (int i = 1;i <= arr.length - 1 ;i++){
int minindex = i-1;
for (int j = i; j <= arr.length - 1; j ++ ){
if (arr[minindex] > arr[j]){
minindex = j;
}
}
int temp = arr[i -1];
arr[i -1] = arr[minindex];
arr[minindex] = temp;
}
}
習慣使用異或來交換的話就覺得理所當然可以這樣寫:
public static void sort(int[] arr){
for (int i = 1;i <= arr.length - 1 ;i++){
int minindex = i-1;
for (int j = i; j <= arr.length - 1; j ++ ){
if (arr[minindex] > arr[j]){
minindex = j;
}
}
arr[i -1] = arr[i -1] ^ arr[minindex];
arr[minindex] = arr[i -1] ^ arr[minindex];
arr[i -1] = arr[i -1] ^ arr[minindex];
}
}
假如你是這樣認為,那么恭喜你進入了陷阱!
輸入陣列
int[] arr = {1,4,4,7,8,9,5,4,6};
結果輸出竟然變成這樣:
[0, 0, 0, 4, 5, 6, 7, 0, 9]
what???
分析結果就知道其原因,并不是因為使用異或的方法不能進行交換,而是因為陣列的索引問題帶來的!
選擇排序原理是將第一個元素假設為最小的一個元素,然后它與之后的元素進行比較,小于這個元素的元素,
就記錄最小元素的索引位置,然后將當前最小的元素繼續與之后的元素進行比較,直到一輪比較完畢,
再將獲得的最小值與假設的最小值位置進行交換.
這樣有可能會出現假設的元素就是實際的最小元素,那么在一輪比較下來,出現
minindex = i - 1,而不是minindex = j;
在minindex = i - 1情況下,
假如i = 1簡化一下就是:
arr[0] = arr[0] ^ arr[0];
arr[0] = arr[0] ^ arr[0];
arr[0] = arr[0] ^ arr[0];
看到這里,你應該就明白了,索引是0的元素竟然是在異或它本身,而我們知道,變數異或它本身,結果是0啊!
因此使用異或寫選擇排序,需要判斷當前索引有沒有改變,即:
if (minindex != i-1){
arr[i -1] = arr[i -1] ^ arr[minindex];
arr[minindex] = arr[i -1] ^ arr[minindex];
arr[i -1] = arr[i -1] ^ arr[minindex];
}
一路分析到這里,我想你也能看出這個陷阱了.
總結就是:
裝大神,使用異或交換兩個變數是有風險的,技術沒學到家會翻車的!
所以我推薦使用第一種方法,簡單明了,可讀性好,于己于人都有利.
uj5u.com熱心網友回復:
uj5u.com熱心網友回復:
強勢圍觀。。。
uj5u.com熱心網友回復:
專家啊,學習了uj5u.com熱心網友回復:
親身體驗,開始還一臉懵。uj5u.com熱心網友回復:
我就是寫快速排序的時候翻車了,還在想怎么會是0
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/105830.html
標籤:Java EE
上一篇:html通過表單檔案域上傳用戶頭像,Servlet處理資料如何顯示出頭像圖片?
下一篇:無法在web.xml或使用此應用程式部署的jar檔案中決議絕對uri:[http://java.sun.com/jsp/jstl/core]
