用异或实现交换,可不用中间变量

前面我们谈到了,可用通过异或运算交换两个数,而不需要任何的中间变量。 如下面:

  1. void exchange(int &a, int &b)
  2. {
  3. a ^= b;
  4. b ^= a;
  5. a ^= b;
  6. }

然而,这里面却存在着一个非常隐蔽的陷阱。

通常我们在对数组进行操作的时候,会交换数组中的两个元素,如exchang(&a[i], &b[j]), 这儿如果i==j了(这种情况是很可能发生的),得到的结果就并非我们所期望的。

  1. void main()
  2. {
  3. int a[2] = {1, 2};
  4. exchange(a[0], a[1]); //交换a[0]和a[1]的值
  5. printf("1---a[0]=%d a[1]=%d\n", a[0], a[1]);
  6. exchange(a[0], a[0]); //将a[0]与自己进行交换
  7. printf("2---a[0]=%d a[1]=%d\n", a[0], a[1]);
  8. }

上面那段测试代码的输出是:

  1. 1---a[0]=2 a[1]=1
  2. 2---a[0]=0 a[1]=1

很意外吧,第一次的交换正确的执行了,但是第二次调用exchange的时候却将a[0]置为了0. 仔细分析,不难发现,这正是我们在exchange里面用异或实现交换所造成的。如果输入a和b是同一个数,exchange里面代码相当于:

  1. a ^= a;
  2. a ^= a;
  3. a ^= a;

成了a做了3次于自己的异或,其结果当然是0了。

既然这样,我们就不能够在任何使用交换的地方采用异或了,即使要用,也一定要在交换之前判断两个数是否已经相等了,如下:

    1. void exchange(int &a, int &b)
    2. {
    3. if(a == b) return; //防止&a,&b指向同一个地址;那样结果会错误。
    4. a ^= b;
    5. b ^= a;
    6. a ^= b;
    7. }
时间: 2024-10-12 12:09:58

用异或实现交换,可不用中间变量的相关文章

网络误区:不用中间变量交换2个变量的value,最高效的是异或运算.

本文记录了不使用中间变量交换2个变量的value,很多的网络留言说是直接异或运算就可以了,而且效率很高,是真的吗? 关于这个问题,网络上面有很多的解释,3种方法,我这里给比较一下各自的优缺点,然后简单分析一下汇编代码,分析代码如下: #include <stdio.h> void swap1(int &a,int &b) { int temp = a; a = b; b = temp; } void swap2(int &a,int &b) { a += b;

不用中间变量,交换a、b值

如果要交换a.b之间的值,一般的做法是: tmp=a;a=b;b=tmp;这种方法不得不使用一个临时变量. 从网上学来一个方法,可以不用使用临时变量: a^=b^=a^=b; 这样计算之后,就可以交换a.b值 证明: 首先:^ 是 位运算 的一种: 异或 运算 1^1=0; 0^0=0; 1^0=1; 0^1=1; 将a.b用二进制表示为: a=An-1 An-2--A1 A0 b=Bn-1 Bn-2--B1 B0 由于a与b进行位运算,是各个bit位分别进行运算,互不影响,下面对某一个位值i上

不用中间变量交换A和B的值

public class SwapAB { public static void main(String[] args) { // 两种值交换的方式,用中间变量空间复杂度高于不用中间变量,但时间复杂度要低于不用中间变量. // 常规写两个值的交换 int a = 100; int b = 200; System.out.println("初始值 a=100 b=200"); // 中间变量 int c; // 复制给中间变量,临时存 c = a; // 把b的值赋给a. a = b;

不用中间变量交换a 和b的值

// 不用中间变量的写法 ,假如 a=13, b=8; a=a+b =21; //此时 a=21; b=8; b=a-b=13; //此时a=21; b=13; a=a-b=8; //相当于 a=21-13=8; // 第二种不用中间变量,换运算,效率比加法高点 a = a ^ b; b = a ^ b; a = a ^ b;

使用异或运算交换两个任意类型变量

这篇文章中将使用C语言,实现交换两个任意类型变量的功能.说到任意类型用C让人感觉很难做,如果是C++则使用模板函数就轻松搞定: template<class T> inline void swap(T& t1, T& t2) { T tmp; tmp = t1; t1 = t2; t2 = tmp; } 先说下使用^来交换两个整数,其代码看着简单但不容易理解 a ^= b; b ^= a; a ^= b; 有人说这种写法很奇葩,但我要说的是,异或运算是计算机很常用的操作.搞懂这

批处理:不用中间变量,交换两个变量值

-------siwuxie095 法一:直接交换(不限) @echo off set var1=abc set var2=123 echo 交换前 :var1=%var1% var2=%var2% set var1=%var2% & set var2=%var1% echo 交换后 :var1=%var1% var2=%var2% pause sublime中: 运行一览: 注意:如果 set var1=%var2% & set var2=%var1% 分开成两段写,就达不到交换的效果了

不用中间变量,交换两个整型变量

突破口:用其中一个变量暂存两者的和. a = a + b; b = a - b;  //此时b已经是a a = a - b;  //相当于(a + b) - a = b

不用中间变量交换两个数 swap(a,b);

#include <iostream> using namespace std; int main () { int a = 3; int b = 5; cout<<"a="<<a<<",b="<<b<<endl; a = a+b; ///a=7 b = a-b; ///b=3; a = a-b; ///a=5 cout<<"a="<<a<<

不用中间变量交换a和b的值?

a = 5 b = 6 a = a+b b = a-b a = a-b print(a,b) a = 5 b = 6 a = a^b b = b^a a = a^b print(a,b) a = 5 b = 6 a,b = b,a print(a,b) 输出 (6, 5) (6, 5) (6, 5) 原文地址:https://www.cnblogs.com/sea-stream/p/11192483.html