如何交换a,b值?且不使用第三个变量!几种方法汇总

在面试的时候,我们经常会遇到这样的问题:如何交换a,b值?且不使用第三个变量!不限语言。
这里我使用javascript作为演示语言。

一、我们先使用最简单的方法。使用临时变量。

let a = 3, b = 5
console.log('default:',`a = ${a}`, `b = ${b}`)
let temp = 0
temp = a
a = b;
b = temp
console.log('a:',a)
console.log('b:',b)

这样的写法优缺点很明显:

语义化非常好易于理解,但是多了声明了一个变量。

二、数学法

let a = 3, b =5;
console.log('default:',`a = ${a}`, `b = ${b}`)
a = a + b
b = a - b
a = a - b
console.log('a:',a)
console.log('b:',b)

这样的方法确实很不错。其实除了以上使用 a = a - b 的方法,还有以下三种:(它们的本质原理与上面的加法原理相同)

// 减法
a = a - b
b = a + b
a = b - a

// 乘法
a = a * b
b = a / b
a = a / b

// 除法
a = a / b
b = a * b
a = b / a

不难看出,数学法的优点省去了变量的声明。但这种方式带来的问题也比较明显:

  • 一、数学法理解起来就没有变量法直观了。
  • 二、由于a,b值的相加(减)会存在溢出的现象。
  • 三、如果a,b有一个值为 0 的话,数学法里面的乘除法就不能使用了

三、异或法

let a = 3, b = 5;
console.log('default:',`a = ${a}`, `b = ${b}`)
a = a ^ b
b = a ^ b
a = a ^ b
console.log('a:',a)
console.log('b:',b)

相较于数学法,异或法更难晦涩难懂了,但是它的优点也非常明显:

  • 一、a,b的值是 0 的情况下也能正常处理
  • 二、值溢出的问题也没有

重点来了!

let obj = { 0: 55 }
let a = 0, b = 0;
obj[a] = obj[a] ^ obj[b]
obj[b] = obj[a] ^ obj[b]
obj[a] = obj[a] ^ obj[b]
console.log(obj[a])
console.log(obj[b])

大家思考一下,上面的代码,最后会输出的是什么呢? 两个 55 ?或者其他。

答案是 0 0

当要交换的两个变量,他们的内存地址指向同一位置的时候,结果就会出现错误。
有兴趣深入了解的同学可以阅读《深入理解计算机系统》–存储器别名

四、转化成对象

let a = 3, b = 5;
console.log('default:',`a = ${a}`, `b = ${b}`)
a=[a,b] // 这里我使用了数组,当然用对象也是可以的
b=a[0]
a=a[1]

// a = {a:b,b:a}; // 这个是使用对象的方法
// b = a.b;
// a = a.a;
console.log('a:',a)
console.log('b:',b)

这样方法,在强类型语言(java c#)里面是行不通的

五、巧用运算符

let a = 3, b = 5;
console.log('default:',`a = ${a}`, `b = ${b}`)
a = a + b - ( b = a ) //方法一
// b = ( a = b ) * 0 + a
 	console.log('a:',a)
console.log('b:',b)

对于第五中方法,我自己理解的也不是很透彻。只是隐隐约约记得大学里面老师好像讲过:当一个语句没有执行结束,其内部的值还是一样的。所以方法一里面虽然先执行了 (b = a)但是b内存里面的值并没有改变,所以可以继续赋值给 a 。由于时间问题,没有找到合适的解释及官方文档,如有大佬知道,烦请留言!

六、后补:解析结构

在群里面我收到了这样的方法:

let a = 3, b = 5;
console.log('default:',`a = ${a}`, `b = ${b}`)
[a, b] = [b , a] //方法一
// a = [b, b = a][0] //方法二
console.log('after:',`a = ${a}`, `b = ${b}`)

其中,
方法一主要利用了es6的语法糖解析结构,是很巧妙,但不适用其他语言。
方法二的做法跟前面转化成对象的方法原理一样。只是写法不同而已!

欢迎加群!!!
群号:799875140

发布了47 篇原创文章 · 获赞 61 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/u011456552/article/details/98962664