编程技巧:使用异或操作符(XOR)交换两数值
异或(exclusive OR)作为4种逻辑操作符之一,相对其他3种(OR/AND/NOT)来说,出场的次数非常少,是因为在日常开发中能用到它的场景本来就不多。对笔者来说,目前接触到场景只有交换两个数值时才会用到。
Java Code:
1 int a = 5; 2 int b = 95; 3 System.out.println(a + ", " + b); 4 5 a ^= b;//等价于 a = a ^ b; 6 b ^= a; 7 a ^= b; 8 System.out.println(a + ", " + b); 9 10 /* 11 * output: 12 * 5, 95 13 * 95, 5 14 */
具体例子:冒泡排序
1 public static int[] bubbleSort(int[] input){ 2 for(int i = input.length - 1; i > 0; i--){ 3 for(int j = 0; j < i; j++){ 4 if(input[j] > input[j + 1]){ 5 input[j] ^= input[j + 1]; 6 input[j + 1] ^= input[j]; 7 input[j] ^= input[j + 1]; 8 } 9 } 10 } 11 return input; 12 }
注意:
- 任何数与0进行异或计算,结果为其自身;
- 任何数与自己进行异或计算,结果为0;
- Java中仅能对byte, short, int或long这4种整数类型(带正负号)进行异或运算,其他类型包括char都不允许(编译错误);
- 第1和第2点Java中不用担心,因为Java中对两个整形变量的异或运算并不是进行数值上的计算,而是对变量的内存地址的交换,因此不存在这两个问题。
使用场景:
对笔者来说,使用该写法的场景只有一个:笔试时的算法题目。这是从避免潜在的不必要的沟通问题方面来考虑。
原理:
逻辑操作符的本质就是对两个二进制数,在单个位级别(bit)的操作。在Java中,由于其他3种已经用于对boolean进行运算,所以剩下异或可以用于位运算。
举最简单的例子来说明,对于两个1bit的二进制数A和B、及它们的异或运算结果C(0或1)来说,在得知任何两个数(AB/AC/BC)的情况下,最后一个数是明确的。
所以
1 a ^= b;// a=a^b 得出c,并赋值给a,即此时a=c; 2 b ^= a;// b=a^b 由于此时a=c,所以实际上是c^b得到a,并赋值给b; 3 a ^= b;// a=a^b 此时b=a,a=c 所以实际上是a^c得到b,并赋值给a,完成a与b的交换