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

原创 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;
版权声明:本文为博主原创文章,未经博主允许不得转载。

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

实现此操作有三种方法: 1)加减法: daima
  • Zidane_2014
  • Zidane_2014
  • 2014年06月24日 22:27
  • 686

不用临时的变量 交换两个数的两种方法

就地交换两个数是比较经典而且基础的算法之一。 我们要交换两个数字,通常的做法就创建一个中间变量,然后进行循环赋值,比如说下面的代码: void Switch(int* p1, int* p2) {...
  • a253664942
  • a253664942
  • 2015年05月09日 16:47
  • 2356

不用第三个变量交换两个变量的值的几种方法

第一次写Blog,心中有些激动o(∩_∩)o 。先在这儿为自己加加油~虽说只是些很简单的小程序,但是我希望自己能够一直坚持下去——做最好的自己,我能!     学过编程的人都知道,在交换两个变量的值时...
  • u011433274
  • u011433274
  • 2013年11月13日 00:21
  • 3645

两个变量的值交换的多种方法

在我的博客“函数参数的传递”(博客地址:http://blog.csdn.net/wxbmelisky/article/details/50833787)一文中谈到过将两个变量的值进行交换的 swa...
  • wxbmelisky
  • wxbmelisky
  • 2016年09月01日 20:48
  • 2096

不用额外变量交换两个整数的值

不用额外变量交换两个整数的值 【题目】   如何不用任何额外变量交换两个整数的值? 【解答】   使用位运算的异或运算,或者使用加法运算   a异或b的结果是c,那么c就是a整数位信息和b整数位信息的...
  • u010456903
  • u010456903
  • 2015年10月04日 23:01
  • 1085

使用异或运算实现两数交换

三种方法实现两数互换
  • zxm1306192988
  • zxm1306192988
  • 2016年01月01日 23:51
  • 2865

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

通常我们的做法是(尤其是在学习阶段):定义一个新的变量,借助它完成交换。代码如下: int a,b; a=10; b=15; int t; t=a; a=b; b=t; 这种算法易于理解,特...
  • KangKermit
  • KangKermit
  • 2014年03月17日 09:32
  • 34762

不用第三方变量如何交换两个数的值

如果要交换两个变量的值,我们首先想到的就是定义一个第三方变量暂存其中一个变量的值:                   如果我们不使用第三方变量怎么交换两个变量的值呢?          ...
  • pt666
  • pt666
  • 2017年04月23日 19:59
  • 640

关于通过异或交换两个元素的值的一个陷阱

#include #include using namespace std; void swap(int *a,int *b){ *a = *a ^ *b; *b = *a ^ *b;//将...
  • qq792326645
  • qq792326645
  • 2015年08月17日 12:43
  • 596

不用第三个变量,直接交换两个变量的值

记得曾经看过不用引进第三个变量而直接变换两个变量的值的例子。见过的两种方法如下: 方法一: var a=1; var b=2; a=a+b; b=a-b; a=a-b; 输出a,b可以发...
  • YEYUANGEN
  • YEYUANGEN
  • 2014年03月19日 11:00
  • 1889
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:不使用临时变量交换两个变量的值(异或,加减,乘除)
举报原因:
原因补充:

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