【问题标题】:How is this method solving my factorial?这种方法如何解决我的阶乘问题?
【发布时间】:2014-10-23 21:12:56
【问题描述】:

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

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

假设我运行 factorial(5) number * factorial(number - 1) 语句中的 else 语句如何迭代 5*4*3*2*1?我知道这可能看起来应该很明显,但这不适合我。提前感谢您的帮助。

【问题讨论】:

    标签: ruby factorial


    【解决方案1】:

    这个概念被称为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 &lt;= 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 语句中它继续通过方法调用自己,-1。当它到达 1 时它停止。对吗?
    • 是的,没错。这是因为该方法仅在评估 else 分支时才调用自身。当 n = 1 时,没有递归调用——只评估 if 分支。
    【解决方案2】:

    当您从else 调用factorial 时,这是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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 2022-06-14
      • 2019-10-14
      • 2020-03-25
      • 2020-02-14
      • 2020-07-30
      相关资源
      最近更新 更多