前不久在刷题过程中,碰到了使用异或来实现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++中有不同的结局,根据编译器的不同,答案会不一样。