异或运算及其在交换变量值中的使用

xiaoxiao2021-02-28  189

在计算机中,如果想要交换变量的值:

Demo1:

常规的算法是

public static void doSwitch(int a,int b){ int temp = a; a = b; b = temp; System.out.println("a:"+a+"b:"+b); }

但是这种方式需要通过第三方变量,

Demo2:

于是又有了第二种算法,

public static void doSwitch2(int a,int b){ a = a+b; //a存入两者之和 b = a-b;//两者之和减去b的值就是a的值,此时,b存入了a的值 a = a-b;//两者值和减去b(a的值),就是b的值 System.out.println("a:"+a+"b:"+b); }

这种算法的思想是先把a+b的和储存在a中,那么 减去b的值则获得a的值,减去a的值则获得b的值。

但是这种算法有可能会出现数值溢出的情况(两个int值相加有可能大于Integer.MAX_VALUE

Demo3

于是有了第三种算法

public static void doSwitch3(int a,int b){ if (a>b){ a = a-b; //a存入两者之差,确保正值 b = b+a;//因为a大b小,则b加上两者之差,为a的值 a = b-a;//a的值减去两者之差,为b的值 } else{ a = b-a;//存下两者之差 b = b-a;//b大a小,b减去两者之差就是a的值 a = a+b;//两者之差加上a的值就是b的值; } System.out.println("a:"+a+"b:"+b); } 这种算法先判断下a,b两个值的大小,用大的减去小的, 确保不溢出,同时存下a-b之差,然后通过差来运算 这种算法明显优于前面两种算法,没有用到第三方变量,也没有溢出的问题。 但是不足之处是使用了if判断,代码量是前两个的两倍。

Demo4

于是有了更好的算法

在介绍之前,先介绍一个概念

位运算:

我们知道,计算机中的数据实际上都是0101,

而位运算其实就是对0101的直接运算。

位运算包含多种运算符,其中一种叫做异或,

在java中用^表示,异或的运算规则为:

如果两个值相同,则运算结果为1,否则为0

如果从单个位上来看,异或运算包含四种情况。

0^1  ==》1

0^0  ==》0

1^1  ==》0

1^0  ==》1

如果我们把上面的运算再算一次,会怎么样呢?

0^1  ==》1   1^1  ==》0

0^0  ==》0   0^0  ==》0

1^1  ==》0   0^1  ==》1 

1^0  ==》1   1^0  ==》1

可以看出,异或对同一个值进行两次运算后,其结果为原来的值

同时,我们可以很明显的看出,异或运算满足交换律,a^b = b^a

继续:

Demo5

于是我们尝试使用异或来进行变量值的交换

public static void doSwitch(int a,int b){ a = a ^ b;//a和b的异或状态储存到a中 b = a ^ b;// 继续异或b则得到a的值 a = a ^ b;//ab之异或后再异或b(a的值)则得到b的值 System.out.println("a:"+a+"b:"+b); }

可以看出,最后一种算法,

既没有使用第三个变量,

也没有溢出问题,代码量也不大。

转载请注明原文地址: https://www.6miu.com/read-23536.html

最新回复(0)