Java的异或运算^,这个小不点“^”就是Java的异或运算符,其特性如下:真^假=真假^真=真  假^假=假  真^真=假,它却是说明了Java异或运算的基本法则,那就是:只要两个条件同时为真或假,其结果都为假(这里要注意区别Java的与运算---其为真真为真,假假为假);但仅当两条件中一个为真,另一个为假时,结果为真(但Java的异或运算还有一个前提那就是它都是以二进制数据为基础进行的运算。也就是说当我们在使用代码中使用到异或运算时,它都会先将两个条件进行转换,转换成二进制数据后,再进行运算,例如:
int a =
4^6;这里的4和6
都是int型数据,在进行运算时,4对应的二进制数为:100(0100);6对应的是:110(0110),这样实际的运算方程是:int
a = 0100^0110;此时再来看:00=0;11=0;01=1;00=0;
这样运算的结果就是:0010(这是二进制的数据),对应转换成十进制就是2.这就是Java里面对于异或运算的内部运算
java交换两个数或字符串可以用temp来交换,如果不使用temp,有下面两种交换方法:
1.对于数来说,可以用
a = a +
b;
b = a - b;
a = a - b;
来进行交换
2.更为通用的方法是用异或来交换
a=a^b;
b=b^a;
a=b^a;
异位运算交换两个整数的算法原理。
交换两个整数常规的实现就是使用临时变量,异位运算交换两个整数不需要临时变量,其实是把临时变量与其中的一个整数结合起来了,也就是说把其中的一个整数当做临时变量来用,这一点与两数相加减的算法是一到致的。下面讲讲原理。
异或运算有两个特性:
1、一个数异或本身恒等于0,如5^5恒等于0;
2、一个数异或0恒等于本身,如5^0恒等于5。
交换两个整数a和b,无非是a=b和b=a这两个操作,当然,你不能直接这么做。该怎么变呢?
算式一:a=b^(a^a)=a^(a^b);
算式二:b=a^(b^b)^(a^a)=a^(a^b)^(a^b);
注意上面算式二中的a还是原来的a,不要认为是改变后的a。
为什么右边的式子都留个a,没为什么,我就是想把b做为临时变量来用,此处要注意,既然做为临时变量用那么b就是最后才计算出来的数。接下来认真的分析下上面的两个算式。得出以下java语句:
把a^b做为临时变量值赋给b(临时变量),得
b=a^b;
计算出a:
a=a^b;注意这时的b可就是上面的式子已改变过的b了。
计算出b:
b=a^b;注意仔细观察上面的式二,此时a=a^(a^b),b=a^b,
(红的为当前的a,b)
至此完成了两个整数的交换。
在程序中实现交换两个数的功能并不复杂,但如果不使用中间变量,就需要动一下脑筋。在本文介绍了两个方法(其实原理都是一个)。其基本原理就是数的中和。也就是说,通过某种运算(二元运算)将a和b两个数变成一个数,并保存在其中一个变量中。然后再通过同样的运算符将a或b中和掉。这样实际上是利用了a或
b本身作为了中间变量。
先看第一个算法。
staticclassNum
{inta;intb;
}publicstaticvoidswap1(Num num)
{
num.a=num.a+num.b;
num.b=num.a-num.b;
num.a=num.a-num.b;
}
上面代码通过“+”运算符将a和b的运算结果赋给了a(这时a是中间变量)。然后再计算b,这时a的值已经是(a+b)了,因此,a再减b就是原来的a。而这时b已经是原来的a了,因此,再用运算后的a(实际上是a+b)减运算后的b(实际上是原来的a),就是原来的b了,最后将这个b赋值给a。
实际上,我们还可以使用“*”、“/”等符号来实现同样的效果,代码如下:
public static voidswap2(Num num)
{
num.a=num.a*num.b;
num.b=num.a/num.b;
num.a=num.a/num.b;
}public static voidswap3(Num num)
{
num.a=num.a-num.b;
num.b=num.a+num.b;
num.a=num.b-num.a;
}
上面代码在Java中没有什么问题(但使用“/”时,分母和分子不能为0)。就算溢出也会得到正确的结果,但有某些语言中(如C语言),可能会抛出溢出错误,不了避免这种错误。可以加判断,代码如下:
public static voidswap4(Num num)
{//不同符号if(num.a*num.b<= 0)
{
num.a=num.a+num.b;
num.b=num.a-num.b;
num.a=num.a-num.b;
}else{
num.a=num.a-num.b;
num.b=num.a+num.b;
num.a=num.b-num.a;
}
}
当然,我们还有更好的方法,就是使用异或运算符,我们知道,任何数与0异或后仍然为它本身,两个相同的数异或后为0。根本这种特性,可以有如下代码。
public static voidswap5(Num num)
{
num.a=num.a^num.b;
num.b=num.a^num.b;
num.a=num.a^num.b;
}
交换a,b两值的方法:
a = a^b;
b = a^b;
a = a^b;
后来想想,真是太神奇了!其实,我们首先知道,对于任意的x满足:
x^x == 0;
x^0 == x;
那么上面的式子事实上是利用了如上的规则,首先用a保存了a^b的 值,再用b = a ^ b =
(a^b)^b=a^b^b=a^(b^b)=a^0=a,这样就成功的实现了b = a;接着又用a = a^b =
(a^b)^b(第一个b还是原来的b,而第二个b已经是a的值,因为前面已经实现了交换)= (a^b)^a = a^a^b = 0^b
= b,这样就实现了a = b;于是,就成功的实现了a,b两个值的交换。