繁体   English   中英

如何在不使用临时变量或算术运算的情况下交换两个数字?

[英]How to swap two numbers without using temp variables or arithmetic operations?

这个方程交换两个没有临时变量的数字,但使用算术运算:

a = (a+b) - (b=a);

如果没有算术运算,我该怎么做? 我在考虑异或。

在 C 中,这应该有效:

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

或者看起来更酷/更怪异的人:

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

有关更多详细信息,请查看 XOR 是一个非常强大的操作,它有很多有趣的用法。

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

这是简单而有效的......

为什么不使用标准库?

std::swap(a,b);

在不使用任何临时存储或算术运算的情况下交换两个数字的最佳方法是将两个变量加载到寄存器中,然后反过来使用寄存器!

你不能直接从 C 中做到这一点,但编译器可能完全有能力为你解决(至少,如果启用了优化)——如果你编写简单、明显的代码,比如 KennyTM 在他的评论中建议的代码.

例如

void swap_tmp(unsigned int *p)
{
  unsigned int tmp;

  tmp = p[0];
  p[0] = p[1];
  p[1] = tmp;
}

使用带有-O2优化标志的 gcc 4.3.2 编译给出:

swap_tmp:
        pushl   %ebp               ;  (prologue)
        movl    %esp, %ebp         ;  (prologue)
        movl    8(%ebp), %eax      ; EAX = p
        movl    (%eax), %ecx       ; ECX = p[0]
        movl    4(%eax), %edx      ; EDX = p[1]
        movl    %ecx, 4(%eax)      ; p[1] = ECX
        movl    %edx, (%eax)       ; p[0] = EDX
        popl    %ebp               ;  (epilogue)
        ret                        ;  (epilogue)

使用异或,

void swap(int &a, int &b)
{
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
}

一个带有 XOR 的衬垫,

void swap(int &a, int &b)
{
    a ^= b ^= a ^= b;
}

这些方法看起来很干净,因为它们不会对任何测试用例失败,但同样因为(如方法 2 中)变量的值在同一序列点内被修改了两次,据说它具有由声明的未定义行为ANSI C.

我以前没有见过这个 C 解决方案,但我相信有人已经想到了。 也许比我有更多的发布自我控制。

fprintf(fopen("temp.txt", "w"), "%d", a);
a = b;
fscanf(fopen("temp.txt", "r"), "%d", &b);

没有额外的变量!

它对我有用,但根据 stdio 实现,您可能需要对输出缓冲做一些事情。

C++11允许:

  • 交换值

     std::swap(a, b);
  • 交换范围

     std::swap_ranges(a.begin(), a.end(), b.begin());
  • 使用tie创建 LValue元组

     std::tie(b, a) = std::make_tuple(a, b); std::tie(c, b, a) = std::make_tuple(a, b, c);
a =((a = a + b) - (b = a - b));

除了上述针对有符号整数的值之一超出范围的情况的解决方案之外,还可以通过这种方式交换两个变量的值

a = a+b;
b=b-(-a);
a=b-a;
b=-(b);

从我的单身汉记得的简单解决方案:-)

a = a+b-(b=a);

例

也可以使用乘法和除法。

 int x = 10, y = 5;

 // Code to swap 'x' and 'y'
 x = x * y;  // x now becomes 50
 y = x / y;  // y becomes 10
 x = x / y;  // x becomes 5

只需使用其他东西,例如一个不是临时的变量。 例如,

int main (int argc, char** argv) {
   int a = 5; int b = 6;
   argc = a; a = b; b = argc;
}

毕竟,问题的关键不在于表明这样做的理智方式( c=a;a=b;b=c )。 这是为了表明你可以开箱即用,或者至少复制其他人的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM