Go语言学习(七)-----练练笔之递归
学了一段时间的Go语言了,今天来见识下Go语言写的递归程序。
先来做个经典题题目:
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
分析:
有以下数学表达式:
Y1=X2+X3 ,Y2=X1 ,Y3=X2+X3
Z1=Y2+Y3 ,Z2=Y1 ,Z3=Y2+Y3
Z1+Z2+Z3= Y2+Y3+Y1+(Y2+Y3)=(Y2+Y3+Y1)+(X2+X3+X1)
因此上面每个月的兔子的数量满足斐波那契数列。斐波那契数列,那就easy了~~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package main import "fmt" func main() { var n float32 = 5 result1 : = fibonacciRecursively(n) fmt.Println(result1) } / / 普通递归方式 func fibonacciRecursively(n float32) float32 { if n < 3 { return 1 } return fibonacciRecursively(n - 1 ) + fibonacciRecursively(n - 2 ) } |
嗯,至此,问题就解决了,不过后来发现,还有一种“尾递归”的做法。
下面换用尾递归来实现上面的斐波纳契数列:
package main import "fmt" func main() { var n float32 = 5 result2 := fibonacciTailRecursively(5, 1, 1) fmt.Println(result2) } //尾递归方式 func fibonacciTailRecursively(n float32, acc1 float32, acc2 float32) float32 { if n == 1 { return acc1 } return fibonacciTailRecursively(n-1, acc2, acc1+acc2) }
使用尾递归,速度确实快了很多。
————————————————摘自百度百科——————————
尾递归是极其重要的,不用尾递归,函数的堆栈耗用难以估量,需要保存很多中间函数的堆栈。比如f(n, sum) = f(n-1) + value(n) + sum; 会保存n个函数调用堆栈,而使用尾递归f(n, sum) = f(n-1, sum+value(n)); 这样则只保留后一个函数堆栈即可,之前的可优化删去。
尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说, 函数调用出现在调用者函数的尾部, 因为是尾部, 所以根本没有必要去保存任何局部变量. 直接让被调用的函数返回时越过调用者, 返回到调用者的调用者去.
————————————————摘自百度百科———————————
再来一个阶乘的尾递归实现Go语言版:
1 package main 2 3 import "fmt" 4 5 func main() { 6 var n float32 = 6 7 fmt.Println(factorialRecursively(n)) 8 fmt.Println(factorialTailRecursively(n,1)) 9 } 10 11 //普通递归 12 func factorialRecursively(n float32) float32 { 13 if n == 1 { 14 return 1 15 } 16 17 return n * factorialRecursively(n-1) 18 } 19 20 //尾递归 21 func factorialTailRecursively(n float32, acc float32) float32 { 22 //0!=1,1!=1,所以这里判断n==0或者n==1都对。 23 if n == 0 { 24 return acc 25 } 26 27 return factorialTailRecursively(n-1, acc*n) 28 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端