博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
不借助变量交换两个数
阅读量:2303 次
发布时间:2019-05-09

本文共 1314 字,大约阅读时间需要 4 分钟。

不借助变量交换两个数

我们在平时写代码的过程之中,竟然会有交换两个变量值的需求。然而我们大多数还是会采用借助额外变量的方式,因为这种方式不仅简单,容易理解,可读性高, 更重要的是适用范围广。那么今天我们来研究一下《如何不借助变量交换两个数》。

借助额外的变量

在正式解这道题之前,我们先用最基础的借助额外变量的方法来做一下。

JavaScript代码:

var a = 1;var b = 2;var temp = a;a = b;b = temp;

这个过程就像交换两个杯子中的水一样,如果不借助任何外物,显然我们不能用常规方法交换两个杯子的水。

640?wx_fmt=png

但是问题转化为数字就变得有可能了 ,我们来看一下。

利用加法

这是最容易想到的方法,整个过程我画了一个图。

640?wx_fmt=png

JavaScript代码:

var a = 1;var b = 2;b = a + b;a = b - a;b = b - a;

但是 a 和 b 的和溢出的风险,其实我们只要稍加变通一下即可。

我们来看下面的代码。

利用减法

这个过程我同样画了一个图,可以看出这次没有出现3了。这在两个数字都非常大,以至于两个加起来 无法用数字表示的时候非常有用。

640?wx_fmt=png

JavaScript代码:

var a = 1;var b = 2;b = a - b;a = a - b;b = a + b;

这种解法没有溢出的风险,理论上已经非常完美了,难道还有更优的解法么?

我们来看一种更加高效的做法。

异或

这里用到了异或这个位运算的性质,即相同则为 0,不同则为 1.

于是对于两个数字,a 和 b。则有 a ^ a ^ b 就等于 b 。我们可以利用这个性质来完成交换。

实际上,有些算法题就可以用这个性质轻松解决。

JavaScript代码:

var a = 1;var b = 2;b = a ^ b;a = a ^ b;b = a ^ b;

逗号表达式

这个方法来自 大徒弟(@wuyuchang)的方法,这个方法利用了逗号表达式的性质。

什么是逗号表达式?逗号表达式是将两个及其以上的式子联接起来,从左往右逐个计算表达式,整个表达式的值为最后一个表达式的值。

因此我们可以利用这个性质,先完成一次赋值操作,然后将赋值操作的返回值变为0. 就可以完成赋值操作

JavaScript代码::

a = b + ((b = a), 0);

扩展

如果数字非常大怎么办?由于数字非常大, 因此我们不能用数字存储了(也不能用 Bit Int)。我们只能使用别的方式存储,比如字符串。这个时候我们不能转化为数字,然后做四则运算, 那么我们怎么办?

这个其实我们可以自己实现一个“加法”或者“减法”,然后思路就和上面一样了。关于这部分,可以参考大数相加[1]实现加法[2]

参考资料

[1]

大数相加: https://lucifer.ren/fe-interview/#/./topics/algorthimn/bigNumberSum

[2]

实现加法: https://lucifer.ren/fe-interview/#/./topics/algorthimn/bitTwoSum

转载地址:http://emcib.baihongyu.com/

你可能感兴趣的文章
迭代序列的三种方法和与序列相关的内建函数
查看>>
用Python实现求最大公约数和判断是否是素数
查看>>
用Python实现一个简单的算术游戏
查看>>
交叉编译linux内核
查看>>
awk简单用法介绍(转)
查看>>
shell脚本中使用MySQL
查看>>
linux --dup dup2 文件描述符重定向函数--输入输出重定向
查看>>
unix/linux中的dup()系统调用 --对上篇dup() dup2()例子的解释
查看>>
这学期读的书
查看>>
编译简介
查看>>
管道编程之pipe
查看>>
网络编程--C/S日期查询例子
查看>>
IPC机制---共享内存编程
查看>>
使用inotify进行文件事件通知
查看>>
Linux中时间函数的应用接口
查看>>
DNS解析过程详解
查看>>
牛奶可乐经济学---阅读总结
查看>>
求最长子序列和
查看>>
计算最大公因数的欧几里德算法
查看>>
在驱动程序中改变进程状态并调用schedule()
查看>>