这个方法是如何解决我的阶乘的



我正在处理一个ruby挑战,必须编写一个方法来计算一个数字的阶乘。我在下面找到了一个解决方案,但我不明白它是如何工作的,特别是else语句中的部分:

def factorial(number)
  if number <= 1
    1
  else
    number * factorial(number - 1)
  end
end

假设我运行阶乘(5)else语句是如何在数字*阶乘(数字-1)语句中迭代5*4*3*2*1的?我知道这似乎应该是显而易见的,但这不适合我。提前感谢你的帮助。

这个概念被称为递归。

factorial(5)评估为

5 * factorial(4)

factorial(4)评估为

4 * factorial(3)

factorial(3)评估为

3 * factorial(2)

factorial(2)评估为

2 * factorial(1)

factorial(1)评估为1,因为1 <= 1

适当地替换值会导致

5 * factorial(4)
5 * 4 * factorial(3)
5 * 4 * 3 * factorial(2)
5 * 4 * 3 * 2 * factorial(1)
5 * 4 * 3 * 2 * 1

else调用factorial时,这是递归的一个示例:从自身调用当前所在的函数。这听起来很奇怪,但你真正要做的是用一个新的参数调用函数的新副本。这意味着流程从函数的顶部重新开始,同时记住完成新副本时返回的位置:

因此,您首先调用factorial(5),它执行以下操作:

def factorial(5)
  if 5 <= 1
    1
  else
    5 * factorial(5 - 1)

现在,在我们继续之前,我们必须调用factorial(5-1)并使用其返回值来替换该表达式。当然,Ruby在调用之前做减法,所以当我们进行递归调用时,参数已经只有4:

  def factorial(4)
    if 4 <= 1
      1
    else
      4 * factorial(4 - 1)

Whups,另一个递归调用。我们又来了:

    def factorial(3)
      if 3 <= 1
        1
      else
        3 * factorial(3 - 1)

再说一遍:

      def factorial(2)
        if 2 <= 1
          1
        else
          2 * factorial(2 - 1)

还有一次:

        def factorial(1)
          if 1 <= 1
            1

稳住你的马!1实际上小于或等于1,所以这次我们没有触及else子句。我们只是在factorial(2)副本中向调用方返回1,所以在它有2 * factorial(1)的地方,我们将factorial(1)替换为返回值,即1:

          2 * 1
        end
      end

因此,现在将2返回给它的调用者,即factorial(3)副本。这意味着3 * factorial(2)变成了3 * 2:

        3 * 2
      end
    end

factorial(4)副本中,4 * factorial(3)变为4 * 6:

      4 * 6
    end
  end

最后,在我们最初的factorial(5)调用的顶部,5 * factorial(4)变为`5*24:

    5 * 24
  end
end  

这当然是想要的答案120。

最新更新