两数交换

  1. int a = 1;
  2. int b = 2;
  3. a = a + b;
  4. b = a - b;
  5. a = a - b;

这个思路很巧妙,但也存在一定问题: 万一溢出了怎么办? 这显然不是正确的做法。
到目前为止,我们的答题思路是没错的,就是寻找另外一种数据存储的模式,用一个变量保存两条信息的集合,我们仍然需要采用这种模式解决这个问题,但原先的简单相加的模式是不行了,于是我们想到,集合两个整型数字,是否可以从其二进制表达方面来考虑?
我们可以使用位异或来存储集合信息。 用 1 和 0 来做简单的验证,看是否可以用异或的方式,存储信息的集合:
如果两个数是a = 1和b = 0,则:
集合 = 1
0 异或 集合 = 1
1 异或 集合 = 0
如果 a = 1 & b = 1
集合 = 0
1 异或 集合 = 1
如果 a = 0 & b = 0
集合 = 0
0 疑惑 集合 = 0
验证结果: 可以采用信息集合的方式存储
那么我们的交换代码可以变成(C的实现):

  1. int a = 10;
  2. int b = 50;
  3. a = a ^ b; // 构建集合
  4. b = a ^ b; // 取出集合的另一个元素
  5. a = a ^ b; // 取出集合的另一个元素


这种方式不用担心数据溢出,应该算是就地交换两个数的最佳解决方案了。
Golang实现:

  1. package main
  2. import (
  3. "os"
  4. "strconv"
  5. )
  6. func main() {
  7. a, _ := strconv.ParseInt(os.Getenv("A"), 10, 64)
  8. b, _ := strconv.ParseInt(os.Getenv("B"), 10, 64)
  9. a ^= b
  10. b ^= a
  11. a ^= b
  12. println("A :", a, "B :")
  13. }