likes
comments
collection
share

代码技巧|变量交换方法

作者站长头像
站长
· 阅读数 40

  整理些代码小技巧和基础知识,为接下来要开的算法专栏做一些铺垫。

  本篇主要分享常用的三种变量交换方法:临时变量交换、加减法交换、异或交换

1.临时变量交换

交互流程

atmpb(1)把a的值copy给tmp临时变量(2)使用b的值更新a,此时a完成交换(3)再使用tmp的值(也就是a的原值)更新b,此时b也完成交换atmpb

代码示例

//临时变量交换
func TestExchange1(t *testing.T) {
   a := 1
   b := 2

   fmt.Printf("a:%d ,b:%d\n", a, b)
   //a:1 , b:2
   
   //(1)把a的值copy给tmp临时变量
   tmp := a
   //(2)使用b的值更新a,此时a完成交换
   a = b
   b = tmp
   //(3)再使用tmp的值(也就是a的原值)更新b,此时b也完成交换
   fmt.Printf("a:%d ,b:%d\n", a, b)
   //a:2 , b:1
}

讲解

  • 依赖一个临时变量tmp完成ab变量的置换
  • 理解简单

2.加减法交换

交互流程

ab(1)将a和b相加,并赋值给a,此时a为a、b之和,此时a非彼时a,如果要区分可以标记为ab(2)将新a(即a、b之和)减去b(得到是原a的值),再赋值给b,就相当于让b更新为a的值,也就完成了b的交换(3)此时,b完成交换,此时b非彼时b,上一轮完成赋值后已经是a的值,因此,a减去b其实是ab之和减去a,真实结果值此时为b,于是用它来更新变量a,也就完成了a变量的交换ab

代码示例

//加减法交换
func TestExchange2(t *testing.T) {
   a := 1
   b := 2

   fmt.Printf("a:%d ,b:%d\n", a, b)
   //a:1 , b:2
    
   //(1)将a和b相加,并赋值给a,此时a为a、b之和,此时a非彼时a,如果要区分可以标记为ab
   a = a + b
   // (2) 将新a(即a、b之和)减去b(得到是原a的值),再赋值给b,就相当于让b更新为a的值,也就完成了b的交换
   b = a - b
   //(3)此时,b完成交换,此时b非彼时b,上一轮完成赋值后已经是a的值,因此,a减去b其实是ab之和减去a,真实结果值此时为b,于是用它来更新变量a,也就完成了a变量的交换
   a = a - b

   fmt.Printf("a:%d ,b:%d\n", a, b)
   //a:2 , b:1
}

讲解

  • 优点是不需要引入新变量,可以基于原变量完成原地交换
  • 缺点是存在数值越界溢出风险

3.异或交换

交互流程

a^bab(1)此时a、b二进制为:a=01、b=10,异或后为11,赋值给a,此时a非彼时a,可以标记为c(2)此时二进制为:a=11(即c)、b=10,异或后为01,赋值给b,此时b完成交换(3)此时二进制为:a=11(即c)、b=01,异或后为10,赋值给a,此时a完成交换a^bab

代码示例

//异或交换
func TestExchange3(t *testing.T) {
   a := 1 
   b := 2

   fmt.Printf("a:%d ,b:%d\n", a, b)
   //a:1 , b:2
   
   //(1)此时a、b二进制为:a=01、b=10,异或后为11,赋值给a
   a = a ^ b 
   //a:3 ,b:2
   
   //(2)此时二进制为:a=11、b=10,异或后为01,赋值给b,此时b完成交换
   b = a ^ b
   //a:3 ,b:1
   
   //(3)此时二进制为:a=11、b=01,异或后为10,赋值给a,此时a完成交换
   a = a ^ b

   fmt.Printf("a:%d ,b:%d\n", a, b)
   //a:2 , b:1
}

讲解

  • 利用异或交换律:a^(b^c) = (a^b)^c
  • 效率高
  • 需要了解二进制异或规律的知识储备进行应用
转载自:https://juejin.cn/post/7216548158972166201
评论
请登录