C++ 在不使用第三个变量的情况下交换两个变量值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1826159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:18:04  来源:igfitidea点击:

Swapping two variable value without using third variable

c++

提问by Muhammad Akhtar

One of the very tricky questions asked in an interview.

面试中提出的非常棘手的问题之一。

Swap the values of two variables like a=10and b=15.

交换两个变量的值,如a=10b=15

Generally to swap two variables values, we need 3rd variable like:

通常要交换两个变量值,我们需要第三个变量,例如:

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

Now the requirement is, swap values of two variables without using 3rd variable.

现在的要求是,在不使用第三个变量的情况下交换两个变量的值。

回答by Yacoby

Using the xor swap algorithm

使用异或交换算法

void xorSwap (int* x, int* y) {
    if (x != y) { //ensure that memory locations are different
       *x ^= *y;
       *y ^= *x;
       *x ^= *y;
    }
}


Why the test?


为什么要考试?

The test is to ensure that x and y have different memory locations (rather than different values). This is because (p xor p) = 0and if both x and y share the same memory location, when one is set to 0, both are set to 0. When both *x and *y are 0, all other xor operations on *x and *y will equal 0 (as they are the same), which means that the function will set both *x and *y set to 0.

测试是为了确保 x 和 y 具有不同的内存位置(而不是不同的值)。这是因为(p xor p) = 0如果 x 和 y 共享相同的内存位置,当一个设置为 0 时,两者都设置为 0。当 *x 和 *y 都为 0 时,*x 和 *y 上的所有其他异或运算将等于0(因为它们是相同的),这意味着该函数会将 *x 和 *y 设置为 0。

If they have the same values but not the same memory location, everything works as expected

如果它们具有相同的值但不相同的内存位置,则一切都按预期进行

*x = 0011
*y = 0011
//Note, x and y do not share an address. x != y

*x = *x xor *y  //*x = 0011 xor 0011
//So *x is 0000

*y = *x xor *y  //*y = 0000 xor 0011
//So *y is 0011

*x = *x xor *y  //*x = 0000 xor 0011
//So *x is 0011


Should this be used?


应该使用这个吗?

In general cases, no. The compiler will optimize away the temporary variable and given that swapping is a common procedure it should output the optimum machine code for your platform.

在一般情况下,没有。编译器将优化掉临时变量,并且鉴于交换是一个常见过程,它应该为您的平台输出最佳机器代码。

Take for example this quick test program written in C.

以这个用 C 编写的快速测试程序为例。

#include <stdlib.h>
#include <math.h>

#define USE_XOR 

void xorSwap(int* x, int *y){
    if ( x != y ){
        *x ^= *y;
        *y ^= *x;
        *x ^= *y;
    }
}

void tempSwap(int* x, int* y){
    int t;
    t = *y;
    *y = *x;
    *x = t;
}


int main(int argc, char* argv[]){
    int x = 4;
    int y = 5;
    int z = pow(2,28); 
    while ( z-- ){
#       ifdef USE_XOR
            xorSwap(&x,&y);
#       else
            tempSwap(&x, &y);
#       endif
    }
    return x + y;    
}

Compiled using:

编译使用:

gcc -Os main.c -o swap

The xor version takes

异或版本需要

real    0m2.068s
user    0m2.048s
sys  0m0.000s

Where as the version with the temporary variable takes:

带有临时变量的版本需要:

real    0m0.543s
user    0m0.540s
sys  0m0.000s

回答by jk.

the general form is:

一般形式是:

A = A operation B
B = A inverse-operation B
A = A inverse-operation B 

however you have to potentially watch out for overflows and also not all operations have an inverse that is well defined for all values that the operation is defined. e.g. * and / work until A or B is 0

但是,您必须潜在地注意溢出,并且并非所有操作都具有为定义操作的所有值良好定义的逆。例如 * 和 / 工作直到 A 或 B 为 0

xor is particularly pleasing as it is defined for all ints and is its own inverse

xor 特别令人愉快,因为它是为所有整数定义的,并且是它自己的逆

回答by Dor

a = a + b
b = a - b // b = a
a = a - b

回答by CB Bailey

No-one has suggested using std::swap, yet.

没有人建议使用std::swap, 。

std::swap(a, b);

Idon't use any temporary variables and depending on the type of aand bthe implementation may have a specalization that doesn't either. The implementation should be written knowing whether a 'trick' is appropriate or not. There's no point in trying to second guess.

不使用任何临时变量,并且根据类型ab实现可能有一个也没有的专业化。编写实现时应该知道“技巧”是否合适。尝试第二次猜测是没有意义的。

More generally, I'd probably want to do something like this, as it would work for class types enabling ADL to find a better overload if possible.

更一般地说,我可能想要做这样的事情,因为它适用于类类型,如果可能的话,它使 ADL 能够找到更好的重载。

using std::swap;
swap(a, b);

Of course, the interviewer's reaction to this answer might say a lot about the vacancy.

当然,面试官对这个答案的反应可能会说很多关于空缺的信息。

回答by Vilx-

As already noted by manu, XOR algorithm is a popular one which works for all integer values (that includes pointers then, with some luck and casting). For the sake of completeness I would like to mention another less powerful algorithm with addition/subtraction:

正如 manu 已经指出的那样,XOR 算法是一种流行的算法,适用于所有整数值(包括指针,有一些运气和转换)。为了完整起见,我想提及另一种功能较弱的加法/减法算法:

A = A + B
B = A - B
A = A - B

Here you have to be careful of overflows/underflows, but otherwise it works just as fine. You might even try this on floats/doubles in the case XOR isn't allowed on those.

在这里你必须小心上溢/下溢,否则它也能正常工作。在不允许 XOR 的情况下,您甚至可以在浮点数/双精度数上尝试此操作。

回答by MSalters

Stupid questions deserve appropriate answers:

愚蠢的问题应该得到适当的回答:

void sw2ap(int& a, int& b) {
  register int temp = a; // !
  a = b;
  b = temp;
}

The only good use of the registerkeyword.

唯一好用的register关键字。

回答by vikas

#include<iostream.h>
#include<conio.h>
void main()
{
int a,b;
clrscr();
cout<<"\n==========Vikas==========";
cout<<"\n\nEnter the two no=:";
cin>>a>>b;
cout<<"\na"<<a<<"\nb"<<b;
a=a+b;
b=a-b;
a=a-b;

cout<<"\n\na="<<a<<"\nb="<<b;
getch();
}

回答by user3258202

Since the original solution is:

由于原始解决方案是:

temp = x; y = x; x = temp;

You can make it a two liner by using:

您可以使用以下方法使其成为两个班轮:

temp = x; y = y + temp -(x=y);

Then make it a one liner by using:

然后使用以下方法使其成为单衬里:

x = x + y -(y=x);

回答by Ashwini

Swapping two numbers using third variable be like this,

使用第三个变量交换两个数字是这样的,

int temp;
int a=10;
int b=20;
temp = a;
a = b;
b = temp;
printf ("Value of a", %a);
printf ("Value of b", %b);

Swapping two numbers without using third variable

在不使用第三个变量的情况下交换两个数字

int a = 10;
int b = 20;
a = a+b;
b = a-b;
a = a-b;
printf ("value of a=", %a);
printf ("value of b=", %b);

回答by Naeem Ul Hassan

#include <iostream>
using namespace std;
int main(void)
{   
 int a,b;
 cout<<"Enter a integer" <<endl;
 cin>>a;
 cout<<"\n Enter b integer"<<endl;
 cin>>b;

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

  cout<<" a= "<<a <<"   b="<<b<<endl;
  return 0;
}

Update:In this we are taking input of two integers from user. Then we are using the bitwise XORoperation to swap them.

更新:在这里,我们从用户那里输入两个整数。然后我们使用按位异或操作来交换它们。

Say we have two integers a=4and b=9and then:

假设我们有两个整数a=4b=9,然后:

a=a^b --> 13=4^9 
b=a^b --> 4=13^9 
a=a^b --> 9=13^9