【趣味数学】不使用第三个变量交换两变量的值(推理过程)

来源:互联网 发布:大数据知识框架 编辑:程序博客网 时间:2024/05/21 15:46

问题:怎么不使用第三个变量交换两个变量的值呢?


解决方案1——数学计算:

1、猜想:

用脚丫想到,似乎加减乘除就能做到这件事吧。然后想一下,如果用乘法很容易爆Int,而且都乘大了,减回来明显不靠谱,除回来除什么?有余数怎么办?也不靠谱。于是基本策略就是只用加减法,那么不妨试一下(a+b)和(a-b)之类的运算,来找一找规律

2、推理:

于是我在纸上写下了:

a = a + b

很明显我发现这是程序语言的写法,左边 a 和右边 a 不好区分,不易推理,于是改成了:

a1 = a0 + b0

a0 和 b0 表示 a 和 b 的初始值,当推理到某一步时若发现:an = b0, bm = a0,则说明交换成功。但切记推理过程中一定要记得这样一点:同字母的变量会被新的赋值覆盖,或者说同字母的变量里只有最新的是有效的。那么接下来不难想到:

 b1 = a1 - b0 = a0

那么很明显最后一步:

a2 = a1 - b1 = b0

证毕。

3、实现代码:

<span style="font-family:Microsoft YaHei;">void mySwap_1(int &a, int &b){    a = a + b;    b = a - b;    a = a - b;}</span>


解决方案2——位运算:

1、猜想:

每个数字都可以表达成 2 进制,即用一串 0、1 表示,那么可不可以通过交换两个数字的 0、1 值来实现交换两个数的值呢?

2、推理:

两个数字放在一起,比较它们的二进制各位中的某一位,无非有四种情况:都是0、都是1、1和0、0和1(后两者其实一样,此处为方便考虑)。不妨举出一个四者皆有的例子,来方便我们思考:

a = 1 0 1 0

b = 1 0 0 1

好的,写在纸上很明显,我们一眼就能发现:若想交换 a、b 的值,则相同位不用变,不同位与自己原来取反即可。同时这个例子列举全了四种情况,例子成功了算法就成功了。接下来,“相不相同、不变、反转”,说到这些想到了什么,没错,就是异或!因为异或运算有这样的特征:

① 相同得 0,不同得 1,可以告诉我们哪些位相同哪些位不同。

② 不管 0 还是 1,与 0 异或都不变

③ 不管 0 还是 1,与 1 异或都反转

那么我们异或一下试试吧:

a1 = a0 ^ b0 = 0 0 1 1

好的,a1 中的 0 表示二者相同,1 表示二者不同。那么 b 直接与 a1 异或,就可以做到相同位不变,不同位取反了:

b1 = b0 ^ a1 = b0 ^ a0 ^ b0 = a0

接下来:

a2 = b1 ^ a1 = a0 ^ a0 ^ b0 = b0

3、实现代码:

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



PS:太久没写C++,使用引用作为函数参数这件事我都忘差不多了。。引用是啥都说不清了,对引用进行操作就像对原变量进行操作是一样的。好吧,我会找时间写一篇博客专门深入研究一下。

0 0
原创粉丝点击