【问题标题】:Is it possible to swap two variables with only += and -= no other operators or variables?是否可以仅使用 += 和 -= 没有其他运算符或变量来交换两个变量?
【发布时间】:2013-05-21 09:53:24
【问题描述】:

我想只使用 +=-= 运算符交换两个变量,而没有临时变量。我知道标准解决方案,例如:

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

xor:

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

但我不知道如何仅使用 +=-=。有可能吗?

【问题讨论】:

  • b -= 2 * b 怎么样?
  • @Tom,再说一遍,* 是不允许的
  • 谁认为这个问题“没有建设性”?这是一个非常精确的问题,有一个非常精确的答案(几行代码或“无法完成”)。它的实际用途可能值得商榷,但从编程/数学的角度来看,它是有效的并且有趣。
  • 我不相信这 4 个运营商 a+=b, a-=b, b+=a, b-=a 是可能的,但我无法证明这一点。
  • 好吧,也许你是对的。你也可以a+=aa-=a,第一个可能有用

标签: c swap


【解决方案1】:

我的同学提供了一个很好的解决方案: 答案是NO

让我们将a 表示为(1 0),将b 表示为(0 1)

矩阵A

1 0
0 1

+=-= 表示相互添加或减去行。这意味着行列式要么不改变其符号,要么等于0。结束矩阵是

0 1
1 0

行列式等于-1,所以你不能得到它

更新: 你有这些操作:

  1. a-=a。一行变成0,所以det=0
  2. a+=a。这意味着将一行乘以2,所以det A'= 2*det A
  3. a+=b。这意味着基本转换,不会改变det 的值
  4. a-=b。与3. 相同

然后将此证明应用于b-=bb+=bb+=ab-=a。所以行列式没有改变它的符号或者是0

更新 2: 正如@Tom 所说,这里是如何在 C# 中执行此操作的示例:http://ideone.com/UzVLML。但是,在 C 语言中这是不正确的:http://codepad.org/Rmhn9iqb。有人可以澄清 C 和 C# 中 b -= b += b 的区别吗?

【讨论】:

  • 你能给我们一个证明,证明彼此相加或相减不会改变行列式的符号
  • @medvedNick:看,这就是为什么我是程序员,而不是数学家:我知道你在说什么,但我只是从表面上看。 ;-)
  • @MOHAMED 用证明更新了答案,为什么行列式不会将其符号更改为 -1
  • @melvedNick b -= b += b 在 C 中是未定义的行为,因为在同一个表达式中有两个对 b 的赋值,没有序列点介入。序列点是更新发生的标记,通常是;&&||bool ? true : false 文章中的?,是函数参数评估和控制从调用者转移到被调用者之间的点,一个函数返回,等等......只需搜索“序列点”和“未定义的行为”,你就会看到。
  • @undefinedbehaviour 这是有道理的。谢谢
【解决方案2】:

虽然 OP 已经证明这是不可能的,但我们可以用现代语言作弊。

        a += b;
        b -= b += b; // Negates b in most languages, but not in C
        b += a;
        a -= b;

【讨论】:

  • 不是a+=ba=a+b 完全一样吗?我以为它在纯C中有返回值。刚刚也测试了它,它不起作用
  • int a = 5; int b = a += 1; 在 C 中编译错误,但在 C++、C# 和 Java 中 b 等于 6
  • 我们说的是int b = a += 1;,对吧? codepad.org/vGBlsszR我们不能改变r-value,但是我们可以用这个值作为其他操作符的输入
  • 在 C 和 C++03 中,b -= b += b; 是未定义的行为,因为有两个写入没有插入序列指向 b 引用的对象。在 C++11(没有序列点)中,我相信赋值表达式中的赋值是在赋值表达式的值计算之前排序的,所以我相信它是有效的。
  • @CharlesBailey:b -= b += b 在 C++11 中仍未定义。 -=运算符左右两边的求值是无序的,也就是说b的修改(右边)和b的值计算(左边)是未排序的,导致未定义的行为。
【解决方案3】:
    a +=b;
    b -=a;
    b =-b;
    a -=b;

【讨论】:

    猜你喜欢
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    相关资源
    最近更新 更多