java异或运算交换两个数的陷阱

我们知道,用异或运算可以不用定义中间变量就可以交换两个数。如下:


<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];
}

 

这样,输出的结果就是正确的了。

总结:以后用到异或运算交换两个数时,首先要想到所有数中有没有自身跟自身交换的情况


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值