使用异或实现swap的错误

前不久在刷题过程中,碰到了使用异或来实现swap的操作,通过a^=b^=a^=b;实现交换a,b。这是一种不需要第三个变量来达到两个整数交换的方法。

于是我把这个swap方法放到了我写的quickSort算法代码中,替代了原有的swap。然而,输出结果却出问题了,顺序不能正常排序,而且有些数据也被改掉了,变成了0.在确定不是我在码代码的时候存在手误的情况下,我开始寻找异或操作不能使用的场景。

在查询原因的过程中,发现了使用这个方法的2个坑。(参考了博客和StackOverflow等论坛)

1.在使用swap操作交换数组元素时,会遇到传入两个下标值相同的情况,这时异或操作实际上变成了

a^=a;a^=a;a^=a;

所以这时a的值会变成0.

解决方法:

public static void swap(int[] arr,int i,int j){
  if(i==j)return;
  a[i]^=a[j];
  a[j]^=a[i];
  a[i]^=a[j];
}

2.在Java中使用a^=b^=a^=b;时,实际运算过程并不是我们想象中那样。虽然它的确是先从右边开始结合的。

在Java中,上述表达式的运行:a=a^(b^=a^=b);其中等式右边最外层的a其实是拷贝值,在执行的时候先对a进行了拷贝,所以虽然右边括号内对a的值进行了修改,但是并没有影响到拷贝的a值,因此答案会出错。这也解释了,为什么b^=a^=b;会正常输出,而a^=b^=a^=b;时就会出错,因为b^=a^=b;等式右边没有修改b的值,所以答案会如预期一样。

当然,这个问题,在c++中有不同的结局,根据编译器的不同,答案会不一样。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值