不使用临时变量交换两个变量的值(异或,加减,乘除)

原创 2015年07月24日 10:30:52

一般我们交换两个变量的值的时候,一般会用到一个辅助变量,像这样

int temp = a;
a = b;
b = temp;

当然,也有一些脚本语言如Python,Lua只需要一行代码就搞定

a,b = b,a

除了使用辅助变量之外,我们还可以通过其他方法来达到交换的目的。

异或

异或有一些有趣的用法,比如这里有用异或的性质求出数组内一个唯一一个只出现一次的元素的例子。

使用异或就不要一个额外的辅助变量了。

a = a^b;
b = a^b;
a = a^b;

我们来看一下真值表就知道这确实能达到交换值的目的了

a b a b a b a b
原始值 0 0 0 1 1 0 1 1
a = a^b 0 0 1 1 1 0 0 1
b = a^b 0 0 1 0 1 1 0 1
a = a^b 0 0 1 0 0 1 1 1


每一位上都发生了交换,两个变量的值自然也就发生了交换

但是,这个方法在特定情况下会有问题。当要交换的两个变量其实是同一个变量的时候,结果就不对。
考虑如下代码:

int[] arr = {99};
int i = 0;
int j = 0;
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];

System.out.println(arr[i]);
System.out.println(arr[j]);

输出为

0
0

结果之所以不对是因为arr[i],arr[j]指向内存中的同一个地址,异或的结果一定是0,最后的结果一定是0。
当在对数组的遍历中需要处理数组元素之间的交换的时候使用了异或这个方法,这种情况确实是有可能发生的。
《深入理解计算机系统》(CSAPP)一书中,就举过类似的例子,书中把这种情况叫做存储器别名

void twiddle1(int *xp, int *yp)
{
  *xp += *yp;
  *xp += *yp;
}
void twiddle2(int *xp, int *yp)
{
  *xp += 2 * *yp;
}

这两个方法的行为貌似是一样的,其实不一定。当指针xp和yp指向同一个位置的时候twiddle1把xp指向位置上的值变为了原来的四倍,twiddle2把xp指向位置上的值变为了原来的三倍

加减

a = a + b;
b = a - b;
a = a - b;

其实可以看成 a = a + b - a, b = a + b - b
这种方法看起来可能会有溢出的问题,但其实试一下就会发现就算a+b大于Integer.MAX_VALUE,出现了溢出,最后的结果还是成功交换了。

乘除

a = a * b;
b = a / b;
a = a / b;
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

不使用第三个变量交换两个变量的值之"异或"的实际应用

交换两个变量的值,不使用第三个变量的四种方法

不借助临时变量交换两个变量的值

如果要交换两个变量的值,一段典型的代码如下:    void swap(type& a, type& b)    {        type temp = a;        a = b;      ...

在不借助第三方变量情况下实现两个变量的交换(借助于异或运算)

下面首先来看一个问题。 假设存在两个int型变量a和b,那么如何实现两个变量值的交换呢。 通常我们的做法,也是最容易想到的做法就是通过定义一个第三方变量,然后借助于该变量来实现变量值的交换。 方...

如何在不使用临时变量的情况下交换两个变量的值?

实现此操作有三种方法: 1)加减法: daima

关于两个变量不使用临时变量进行值交换

最近,由于工作需要的,重温了一下数据结构与算法分析

交换两个数不使用第三方变量=!!=深入理解按位异或运算符

不使用第三方变量交换两个变量的值这需要进行位操作,必较麻烦的, 在学习程序语言和进行程序设计的时候,交换两个变量的值是经常要使用的。通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完...

使用异或运算交换两个变量的危险

我们知道,在排序算法中经常会需要交换序列中的两个变量,常见有两种方法: 1.借助第三个临时变量 // 交换 int temp = array[i]; array[i] ...

变量互换方法,中间变量 加减 异或

最常用的变量互换方法是采用中间变量:void swap(int *a,int *b) { int tmp = *a; *a = *b; *b = tmp; }不用中间变量也可以...

表达式求值:从“加减”到“带括号的加减乘除”的实践过程

本文乃Siliphen原创,转载请注明出处:http://blog.csdn.net/stevenkylelee    ● 为什么想做一个表达式求值的程序   最近有一个需求,策划想设置游戏关卡的...

不用临时变量顺次交换N个变量的值

有N(N>=2)个变量,不使用临时变量,如何顺次交换它们的值?能否只用一条语句实现?如+—+—+—+—+—+ | a | b | c | d | e | +—+—+—+—+—+ | 1 | 2 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:不使用临时变量交换两个变量的值(异或,加减,乘除)
举报原因:
原因补充:

(最多只允许输入30个字)