【问题标题】:Understanding, Recursion in Ruby理解,Ruby 中的递归
【发布时间】:2013-05-21 04:52:20
【问题描述】:

在递归中,方法调用自身。当有返回值时,我不关注它。例如,在 Chris Pine 的“学习编程”一书中,有这个关于阶乘的示例。

def factorial num 
  if num < 0
    return 'You cant\'t take the factorial of a negative number!'
  end
  if num <= 1
    1
  else 
    num * factorial(num-1)
  end
end 

如果我调用factorial(3) 方法,它将转到代码的else 部分,如下所示:

3 * factorial(3-1)

并且应该返回6,因为3*2=6factorial(3-1) 调用 factorial 方法,在递归中传递 2num = 2,因此 2 * factorial(2-1)2*1=2

我们第一次运行代码时得到的6 会发生什么变化?现在是num = 1,看起来现在将返回1 并转到代码的末尾。但据我了解,我们仍然有来自先前递归的62。我在这个假设中是否正确,因为当我们乘以 num 时我们调用了阶乘函数?有人可以帮助我更好地理解这一点吗?假设我们调用了factorial(10),这将如何解决?

【问题讨论】:

  • 你看《盗梦空间》了吗?
  • 所有这些代码......当你所要做的就是:def fact(n) (1..n).inject(1) {|r,i| r*i } end :)
  • 阶乘函数总是被用作递归的一个例子,当它是一种可怕的解决问题的方法时。我认为这对初级程序员造成了各种脑损伤,因为每个问题都需要通过递归而不是像堆栈这样的适当技术来解决。

标签: ruby recursion factorial


【解决方案1】:

现在我们从第一次运行中得到的 6 会发生什么? 代码?

第一次运行没有 6 个; 6只出现在最后。

会发生这样的事情:

factorial(3) → 3 * factorial(2)
factorial(3) → 3 * 2 * factorial(1)
factorial(3) → 3 * 2 * 1

你的函数中没有以前调用的“记忆”,每次调用 factorial() 时,它就像一个全新的函数;写成多个函数会更清楚吗?

def factorialof3
  3 * factorialof2
end

def factorialof2
  2 * factorialof1
end

def factorialof1
  1
end

【讨论】:

    【解决方案2】:

    Patrice 回答将其拆分为单独的函数很好,如果您有任何计算机科学背景,考虑一下可能在这里工作的数据结构也将有所帮助,主要是 Stack

    因此,当您调用 factorial(3) 时,它将转到 else 块并在另一次调用 factorial(2) 时“堆栈”

    然后通过调用factorial(1) 来堆叠另一个。

    此时,由于num = 1,(递归必须始终有一个基本情况)factorial(1) 将返回 1。

    然后由于堆栈,最后一个入是第一个出,所以阶乘(1)将返回 1,这将“回落”到 factorial(2) 调用,因为它被调用那个 else 块,对 factorial(2-1) 的调用现在将被 1 替换,你将得到 2*1,我想现在你已经明白了

    同样需要注意的是,这个例子是试图教你一般的递归,这个例子并不是真正地道的 ruby​​。作为评论发布的解决方案alfasin更像它。

    【讨论】:

      【解决方案3】:

      首先,您应该将 return 'blabla' 替换为 raise 'blabla',因为您的函数返回的是数字,而不是字符串。

      那就这样看

      factorial(3)
        3 * factorial(2)
              2 * factorial(1)
                    1  # no more recursion, let's go up replacing 
                       # the function calls by the returned value
                  end
            end
      end
      # ↓
      factorial(3)
        3 * factorial(2)
              2 * 1  # let's go up again !
            end
      end
      # ↓
      factorial(3)
        3 * 2 # finally
      end
      # ↓
      6
      

      【讨论】:

        猜你喜欢
        • 2012-07-26
        • 2014-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-05
        • 2014-01-28
        相关资源
        最近更新 更多