zoukankan      html  css  js  c++  java
  • 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了~~

    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 }
  • 相关阅读:
    Python学习笔记(三)- 变量
    Python学习笔记(二)-程序执行原理
    Python学习笔记(一)
    牛客算法周周练7-A-收集纸片-dfs解决图的路径问题
    HihoCoder1078-线段树的区间修改-线段树区间修改、查询-模板题
    POJ1298-字符串转换-水题
    java的内存分析(内存模型)
    Linux的自有服务-SSH服务(重点)
    js-类似邮箱中的删除文件-全选、不选、反选
    jmeter数据分析,压测实现
  • 原文地址:https://www.cnblogs.com/yejg1212/p/2991133.html
Copyright © 2011-2022 走看看