java異或運算交換兩個數的陷阱
阿新 • • 發佈:2019-02-01
我們知道,用異或運算可以不用定義中間變數就可以交換兩個數。如下:
<span style="font-size:14px;">int a=2;
int b=3;
System.out.println("交換前:a="+a+" b="+b);
a=a^b;
b=a^b;
a=a^b;
System.out.println("交換後:a="+a+" b="+b);</span>
輸出的結果是:
交換前:a=2 b=3
交換後:a=3 b=2
這樣看來,使用異或運演算法則交換兩個數的方法確實很好用。但是我們在某些特殊的地方使用它就要小心了,比如我們在選擇排序演算法中使用它時:
<span id="_xhe_cursor"></span><span style="font-size:12px;">package com.test; public class Test { public static void main(String[] args) { int a[] = { 5, 3, 7, 9, 0, 2, 1, 4, 6, 8 }; Select select = new Select(); select.sort(a); // 遍歷輸出排好的陣列 for (int i : a) { System.out.print(i + " "); } } } // 選擇排序類 class Select { public void sort(int a[]) { for (int j = 0; j < a.length - 1; j++) { int min = a[j];// 最小的值 int minLndex = j;// 最小值的下標 for (int k = j + 1; k < a.length; k++) { if (min > a[k]) { min = a[k]; minLndex = k; } } // 使用異或運算交換兩個數 a[j] = a[j] ^ a[minLndex]; a[minLndex] = a[j] ^ a[minLndex]; a[j] = a[j] ^ a[minLndex]; } } }</span>
輸出的結果是:0 1 2 3 4 5 6 0 8 9
為什麼呢?
其實我們知道,異或運算a^a=0,我們仔細分析一下可以發現在選擇排序演算法中就有a^a的情況,所以出現上面這樣的結果也就不奇怪啦。
對於以上bug,我們可以這樣解決:
在交換之前先判斷
<pre class="java" name="code">if(a[j]!=a[minLndex])
{
a[j]=a[j]^a[minLndex];
a[minLndex]=a[j]^a[minLndex];
a[j]=a[j]^a[minLndex];
}
這樣,輸出的結果就是正確的了。
總結:以後用到異或運算交換兩個數時,首先要想到所有數中有沒有自身跟自身交換的情況