【问题标题】:Is using base case variable in a recursive function important?在递归函数中使用基本情况变量重要吗?
【发布时间】:2020-10-22 00:39:40
【问题描述】:

我目前正在学习递归,这很难理解。我找到了一个非常常见的例子:

function factorial(N)
    local Value
    if N == 0 then 
        Value = 1 
    else
        Value = N * factorial(N - 1)
    end 
    return Value
end
print(factorial(3))

N == 0 是基本情况。但是当我将其更改为N == 1 时,结果仍然保持不变。 (它将打印 6).

使用基本情况重要吗? (它会坏掉还是什么?)

使用N == 0(基本情况)和N == 1有什么区别?

【问题讨论】:

  • 如果将基本情况更改为N == 1,那么factorial(0) 将导致无限循环。在每个递归函数中都必须是基本情况。所以递归“知道”什么时候停止。你有一个example 阶乘函数如何解析 N = 4。
  • 很好的解释和例子,谢谢

标签: function recursion lua


【解决方案1】:

这只是一个巧合,因为1 * 1 = 1,所以它最终会以任何方式工作。

但考虑N = 0 的边缘情况,如果您检查N == 1,那么您将进入else 分支并计算0 * factorial(-1),这将导致无限循环。

如果您只是直接调用factorial(-1),这两种情况都会发生同样的情况,这就是为什么您应该检查> 0(有效地将每个负值视为0并返回1,或者添加另一个if条件并在N 为负数时引发错误。


编辑:正如另一个答案中所指出的,您的实现不是尾递归的,这意味着它会为每个递归函数调用累积内存,直到它完成或内存不足。

您可以使函数尾递归,这允许 Lua 将其视为一个正常循环,只要计算其结果就可以运行:

local function factorial(n, acc)
   acc = acc or 1
   if n <= 0 then
      return acc
   else
      return factorial(n-1, acc*n)
   end 
   return Value
end
print(factorial(3))

但是请注意,在阶乘的情况下,用完堆栈内存比在 21! 附近溢出 Luas 数字数据类型需要更长的时间,因此使其尾递归实际上只是一个问题训练自己编写更好的代码。

【讨论】:

  • 很高兴知道,我已经将“ if N == 0 or N
  • 在这种情况下你可以做if N &lt;= 0 then:D
【解决方案2】:

正如上面的答案和 cmets 所指出的,在递归函数中必须有一个基本情况;否则,最终会陷入无限循环。

另外,对于阶乘函数,使用辅助函数执行递归可能更有效,以便利用 Lua 的尾调用优化。由于 Lua 方便地允许本地函数,因此您可以在阶乘函数的范围内定义一个助手。

请注意,此示例并非旨在处理负数的阶乘。

-- Requires: n is an integer greater than or equal to 0.
-- Effects : returns the factorial of n.
function fact(n)
    -- Local function that will actually perform the recursion.
    local function fact_helper(n, i)
        -- This is the base case.
        if (i == 1) then
            return n
        end
        -- Take advantage of tail calls.
        return fact_helper(n * i, i - 1)
    end
    -- Check for edge cases, such as fact(0) and fact(1).
    if ((n == 0) or (n == 1)) then
        return 1
    end
    return fact_helper(n, n - 1)
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多