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

时间:2014-10-23 21:12:56

标签: ruby factorial

我正在研究一个红宝石挑战,并且必须编写一个方法来计算一个数字的因子。我在下面遇到了一个解决方案,但我不明白它是如何工作的,特别是else语句中的部分:

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

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

2 个答案:

答案 0 :(得分:5)

这个概念被称为recursion

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

答案 1 :(得分:1)

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

所以你先拨打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.