最常见的应用的话我想应该是排序吧,比如给你一个数组,让你按照从小到大或者从大到小的顺序排序,比如下面用冒泡法排序:
int[] num=new int[]{4,7,15,1,6,9,3,40,2};
int tem=0;
//普通方式:
for (int i=num.length-1; i>0; i--){
for(int j=0; j<i; j++){
if (num[j+1]<num[j]){
tem=num[j+1];
num[j+1]=num[j];
num[j]=tem;
}
}
}
//如果我们使用异或运算实现就是:
for (int i=num.length-1; i>0; i--){
for(int j=0; j<i; j++){
if (num[j+1]<num[j]){
num[j+1] = num[j+1] ^ num[j];
num[j] = num[j+1] ^ num[j];
num[j+1] = num[j+1] ^ num[j];
}
}
}
两个方法的结果是一样的。第二个方法抽象出最简单的模式的话就是你的题目中所展示的一样,原理是这样的:
int n=3,m=8;
n = n ^ m;
m = n ^ m; //(n^m)^m
n = n ^ m; //n^(n^m)
3对应的二进制数为0000 0011,8对应的二进制数为0000 1000,二者取异或结果为0000 1011,对应的十进制为11,将其赋给n,然后0000 1011与0000 0011取异或的结果为0000 1000,即8,赋给m,最后0000 1011与0000 1000取异或的结果为0000 0011,即3赋给n。这样就将两个数组进行了替换,你可以试着将这个替换过程想象成两个人玩牌的游戏,每个人有8张牌(这里的牌只有状态没有大小之分),彼此对应,两个人都想获得对方的牌的状态信息。每张牌有显示(0)和掩饰(1)两个状态,其中一个人根据另一个人的牌的状态调整自己对应牌的状态,当两个人对应的牌都显示或都掩饰时,其中一个人将自己的这个牌设为显示,而如果对应牌状态不同,就奖牌设为掩饰。第一个人奖牌调整之后,第二个人再根据第一个人现在牌的状态进行相同的调整,然后第一个人根据第二个人的现在牌的状态进行调整,很容易就会看到第一个人会得到第二个人牌的初始状态,第二个人得到了第一个人的初始状态。
可能最后的类比不是最恰当的,不过还是挺有趣的。不知道有没有回答您的问题。
|