多方法实现 swap 2 个 int 变量的值

最常用方法是用临时变量保存备份值

void swap(int &x, int &y)
{
    int temp = x;
    x = y;
    y = temp;
}

不使用临时变量,方法是:按位异或 及 四则运算实现

#include <iostream>
#include <limits>
using namespace std;
void swap(int &x, int &y)
{
    x ^= y;
    y = x ^ y;
    x = x ^ y;
}
void swap1(int &x, int &y)
{
    x = x + y; // 即使溢出,结果仍正确
    y = x - y;
    x = x - y;
}
void swap2(int &x, int &y)
{
    x = x - y; // x - y 丢失数据
    y = x + y;
    x = x + y;
}
void swap3(int &x, int &y)
{
    x = x * y; // x*y 可能溢出
    y = x / y;
    x = x / y;
}
void swap4(int &x, int &y)
{
    x = y / x;
    y = y / x; // x = 0 出错
    x = x * y;
}
 int main(void)
{
    int x = numeric_limits<int>::max();
    int y = numeric_limits<int>::max()-1;

    // x = 1, y = 2;
    cout << "原值" << x << " " << y << endl;

    swap(x, y);
    swap(x, y);
    cout << "swap 异或:";
    cout << x << " " << y << endl;

    swap1(x, y);
    swap1(x, y);
    cout << "swap 加:";
    cout << x << " " << y << endl;

    swap2(x, y);
    swap2(x, y);
    cout << "swap 减:";
    cout << x << " " << y << endl;

    // swap3(x, y);
    // cout << "swap 乘:";
    // cout << x << " " << y << endl;

    // swap4(x, y);
    // cout << "swap 除:";
    // cout << x << " " << y << endl;

    cout << "===========" << endl;
    x = numeric_limits<int>::min();
    y = numeric_limits<int>::min()+1;
    cout << "原值" << x << " " << y << endl;
    swap(x, y);
    swap(x, y);
    cout << "swap 异或:";
    cout << x << " " << y << endl;

    swap1(x, y);
    swap1(x, y);
    cout << "swap 加:";
    cout << x << " " << y << endl;

    swap2(x, y);
    swap2(x, y);
    cout << "swap 减:";
    cout << x << " " << y << endl;
}

运行结果为:

原值2147483647 2147483646
以下交换使用一种方法均进行交换2次,如仍输出原值,结果正确
swap 异或:2147483647 2147483646
swap 加:2147483647 2147483646
swap 减:-2147483647 -2147483648
===========
原值-2147483648 -2147483647
swap 异或:-2147483648 -2147483647
swap 加:-2147483648 -2147483647
swap 减:2147483646 2147483647
[Finished in 0.4s]

由以上结果分析,只有通过按位异或的方式和用一个变量保存和(虽然溢出但结果正确)的方式能正确实现交换。

// 异或
void swap(int &x, int &y)
{
    x ^= y;
    y = x ^ y;
    x = x ^ y;
}
// 用 x 保存 x+y 的和
void swap1(int &x, int &y)
{
    x = x + y;
    y = x - y;
    x = x - y;
}

其他方式,如通过保存2个变量的差/积/商,对于某些数据可能输出正确结果,但是对于可能溢出的数据,不能实现正确的交换

结论

除了使用临时变量实现交换的方法外,还可以用按位异或 和 用其中一个变量保存和的形式实现交换2个整型变量。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-15 19:28:49

多方法实现 swap 2 个 int 变量的值的相关文章

js判断一个值是空的最快方法是不是if(!value){alert(&quot;这个变量的值是null&quot;);}

!逻辑非 操作符(js)-操作于任何值,(!undefined)(!Null)(!任何对象)(!"")(!"lihuan")(!任何非零数字值) (!0)(!NaN)(!true)(!false):逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反:undefined- false/Null-false/任何对象-true/""-false/"lihuan"-true/任何非零数字-true/0-false /Na

int变量赋值给char变量的本质

本质上,int变量将其最低一个字节的内容,赋值给char变量. 如下代码: int a = 0xFFFFFF41; char c = a; printf("c: %c\n", c); 根据小端存储模式,a的低位一字节存放的是十六进制数41,它的十进制数是65,对应的ASCII字符是A. 由于a的低位一字节内容赋值给了c,因此c的值就是十进制数65,输出字符结果为A.

PHP不用第三变量交换2个变量的值的解决方法

以前做过一道php面试题是这样的:不使用第三个变量实现交换两个变量的值.一般都是借助第三个中间变量来实现原来两个变量的值交换,但是这道题却要求不能使用中间变量,这对于初学者来说也算是一个难题了.网上找到的几种方法总结如下: 复制代码 代码如下: //字符串版本 结合使用substr,strlen两个方法实现 $a="a";$b="b";echo '交换前 $a:'.$a.',$b:'.$b.'<br />';$a.=$b;$b=substr($a,0,(

转:【Java并发编程】之十五:并发编程中实现内存可见的两种方法比较:加锁和volatile变量

转载请注明出处:http://blog.csdn.net/ns_code/article/details/17290021 在http://blog.csdn.net/ns_code/article/details/17288243这篇博文中,讲述了通过同步实现内存可见性的方法,在http://blog.csdn.net/ns_code/article/details/17101369这篇博文中,讲述了通过volatile变量实现内存可见性的方法,这里比较下二者的区别. 1.volatile变量

【Java并发编程】之十五:并发编程中实现内存可见的两种方法比较:加锁和volatile变量

在http://blog.csdn.net/ns_code/article/details/17288243这篇博文中,讲述了通过同步实现内存可见性的方法,在http://blog.csdn.net/ns_code/article/details/17101369这篇博文中,讲述了通过volatile变量实现内存可见性的方法,这里比较下二者的区别. 1.volatile变量是一种稍弱的同步机制在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种

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

//交换两个变量的值,不使用第三个变量. //有两种解法, 一种用算术算法, 一种用^(异或) //异或:相同为0,不同为1.相当于减法. #include <stdio.h> int main() { int a = 8; int b = 9; printf("初始状态:a = %d, b = %d\n",a,b); a = a + b; b = a - b; a = a - b; printf("算数交换:a = %d, b = %d\n",a,b)

异常处理:写一个方法void triangle(inta,intb,int c),判断三个参数是否能构成一个三角形。

写一个方法void triangle(inta,intb,int c),判断三个参数是否能构成一个三角形.如果不能则抛出异常IllegalArgumentException,显示异常信息:a,b,c "不能构成三角形":如果可以构成则显示三角形三个边长.在主方法中得到命令行输入的三个整数,调用此方法,并捕获异常. import java.util.Arrays;import java.util.Scanner; public class ExceptionTest1 { public

《Java中方法的参数传递方式只有一种:值传递》

1 //方法的参数传递机制(1):基本类型做形参的传递. 2 class PrimitiveTransferTest 3 { 4 public static void swap(int a,int b) 5 { 6 //下面代码实现a和b交换 7 int temp = a; 8 a = b; 9 b = temp; 10 System.out.println("swap方法里,a的值是:"+a+",b的值是:"+b); 11 } 12 public static v

交换变量的值

方法一:借助第三方变量 1 #region 1 利用第三方变量 2 int a = 10; 3 int b = 20; 4 Console.WriteLine("交换前的值:a={0},b={1}", a, b); 5 Console.ReadKey(); 6 int temp = a; 7 a = b; 8 b = temp; 9 Console.WriteLine("交换后的值:a={0},b={1}", a, b); 10 Console.ReadKey();