隔空换物——数学魔法和它的应用

隔空换物——数学魔法和它的应用

首页休闲益智独角兽数学更新时间:2024-04-26

两只箱子。左边箱子装着一只猫,右边箱子放着一只兔子。如何让猫和兔子交换位置,变为兔子装在左边箱子里,猫放在右边箱子呢?

这是一个很简单的问题。你问我的话,我给出的办法简单,就两步。

第一步,把兔子放进左边箱子;

第二步,把猫猫放进右边箱子。

你还能想出更简单的方法来吗?

衍生出来的问题就是,设定有两个对象A1和A2, A1的值为V1, A2的值为V2。然后求如何交换两对象的值,使其A1的值为V2,A2的值为V1。从程序代码层级加以实现。

解法一:通过一个临时的对象来实现值的交换。这是每本编程入门教科书都会提到的解法。

#include <iostream> void swap(int &v1, int &v2) { int t = v1; v1 = v2; v2 = t; } int main() { int a1 = 42; int a2 = 13; swap(a1, a2); std::cout << "a1: " << a1 << " a2: " << a2 << std::endl; return 0; }

解法二:闭门造车不如草船借箭。有没有现成的东东借来一用呢?还真有!在C 的标准库STL定义了一个通用函数swap。

#include <iostream> #include <algorithm> #include <string> using namespace std; int main() { string left_box = "pussy"; string right_box = "bunny" swap(left_box, right_box); std::cout << "left box: " << left_box << " right box: " << right_box << std::endl; return 0; }

解法三:数学魔法来啦。自定义一个函数swap。神奇藏在swap函数体里面。没有借助任何资源, 两对象交换了各自的值!

#include <iostream> #include <string> using namespace std; //----------------------------------------------------------------------------- // swap the two objects by a hacking trick with ^ operation (XOR) // (a^b)^a = b // (a^b)^b = a //----------------------------------------------------------------------------- template<typename T> void swap(T &lhs, T &rhs) { if (lhs != rhs) { lhs = lhs ^ rhs; rhs = lhs ^ rhs; lhs = lhs ^ rhs; } } int main() { string left_box = "pussy"; string right_box = "bunny"; swap(left_box, right_box); std::cout << "left box: " << left_box << " right box: " << right_box << std::endl; }

神奇魔法依赖布尔代数中的一个结论。布尔代数中用^来表示异或运算。^的运算规则用如下图示说明。

0 ^ 0 = 0

0 ^ 1 = 1

1 ^ 0 = 1

1 ^ 1 = 0

由此容易推得一个神奇的结论:

(a^b)^a = b

(a^b)^b = a

你可以这么理解。a和b是两个物件,通过异或操作,a^b,形成合体;钥匙是a或者b,借助上面的结论,我们能完美地分别提取出藏在a^b合体中的a和b——用钥匙a,提取出b;用钥匙b,提取出a。

空谈误事。上代码。你看如下的代码中,swap函数体没有创建任何临时变量,没有借助库函数,只用了三次异或位运算^就让传入的两个对象的值互换了!

void swap(T &lhs, T &rhs) { lhs = lhs ^ rhs; rhs = lhs ^ rhs; lhs = lhs ^ rhs; }

这不是一种魔法吗?数学就是这么神奇。


更多相关资料,敬请关注头条号“独角兽电波”。





查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved