【问题标题】:Recursion instead of looping [closed]递归而不是循环[关闭]
【发布时间】:2018-11-25 20:46:35
【问题描述】:

我是 Go 编程新手,那么如何在这段代码中实现递归而不是 for 循环?

package main

import (
    "fmt"
)

func main() {
    var n int
    fmt.Scan(&n)
    set(n)
}

func set(n int) {
    a := make([]int, n)
    for i := 0; i < n; i++ {
        fmt.Scan(&a[i])
    }
    fmt.Println(a)
}

【问题讨论】:

    标签: arrays loops go recursion


    【解决方案1】:

    我不确定你想递归什么。但是,正如我将您的问题理解为将 for 循环更改为递归一样,我以函数式编程风格将其变为闭包中的尾递归。

    func set(n int) {
        a := make([]int, n)
        var setRecursive func(int) // declare a function variable, which take an int as param.
        setRecursive = func(i int) { // set the function in closure, so a and n is available to it.
            if i == 0 { // end point of the recursion, return.
                return
            }
            Scan(&a[n-i]) // Use fmt.Scan out of playground
            setRecursive(i - 1) // tail recursion.
        }
        setRecursive(n) // call the function, start the recursion.
        fmt.Println(a)
    }
    

    如果你想让事情更简单,你可以去掉闭包部分,将Scan(&amp;a[n-i])行移到setRecursive(n)行后面,如下所示:

    func SetRecursive(a []int, n int) {
        if n==0 {
            return
        }
    
        SetRecursive(a,n-1) // recurse first, so we can scan in the right order.
        Scan(&a[n-1])
    }
    

    游乐场:https://play.golang.org/p/0io190tyviE

    【讨论】:

      【解决方案2】:

      我的语法可能有点不对劲,所以我评论了每一行的作用。本质上,您每次都会获得数组的一项,并在其前面附加一个较小的数组,您可以通过获取一个值并在其前面附加一个较小的数组,直到该值为 1 和你只是得到了一个价值。

      func set(n int) []int {    // declare a function that takes an int as a parameter
                                 // and returns an int array
          var recRet = []int{}       // need a temporary array to store return value
          a := make([]int, 1)        // make an array of one to get the value this iteration
          if n < 1 {                   //should never be here but prevents looping
             return nil              // escape
          }
          if n > 1 {                  // if we're not in the base case
              recRet = set(n-1)      // recurse on a list one smaller and store it
          }
      
          fmt.Scan(&a[1])            // get the value for this iteration
          fmt.Println(a)             // print it
          return append(a, recRet...)// send this value plus the values gotten from recursion
                                     // back up
      }
      

      【讨论】:

      • 此代码不起作用。 return null 是一个错误,因为 Go 中没有 nullfmt.Scan(&amp;a[i]) 是一个运行时错误,因为a 始终是len=1 cap=1 的一部分,而a[i] 在 i>1 时会因为超出范围而发生恐慌。
      猜你喜欢
      • 1970-01-01
      • 2010-09-17
      • 2021-03-20
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      • 2012-11-12
      • 2014-03-02
      相关资源
      最近更新 更多