recursion - Scheme 中的尾递归函数

标签 recursion scheme lisp tail-recursion

我正在准备圣诞节考试并做一些考试样本,我遇到了这个让我有点困惑的问题

Question

我可以很好地执行常规递归,但我无法理解如何使用尾递归编写相同的内容。

普通版:

    (define (factorial X)
      (cond
            ((eqv? X 1) 1)
            ((number? X)(* X (factorial (- X 1))))))

最佳答案

对于尾递归函数,函数返回后除了返回其值之外不能执行任何操作。也就是说,递归步骤中发生的最后一件事是对函数本身的调用。这通常是通过使用累加器参数来跟踪答案来实现的:

(define (factorial x acc)
  (if (zero? x)
      acc
      (factorial (sub1 x) (* x acc))))

上面的过程最初将使用 1 作为累加器来调用,如下所示:

(factorial 10 1)
=> 3628800

请注意,当达到基本情况时,会返回累积值,并且 acc 参数会在递归调用中的每个点进行更新。我必须向该过程添加一个额外的参数,但这可以通过定义内部过程或命名的 let 来避免,例如:

(define (factorial x)
  (let loop ((x x)
             (acc 1))
    (if (zero? x)
        acc
        (loop (sub1 x) (* x acc)))))

关于recursion - Scheme 中的尾递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13664639/

相关文章:

haskell - 是否有纯函数式的方案或 Lisp?

javascript - 有人可以向我解释如何将这个递归函数添加到自身吗?

algorithm - 三个正数 x、y、z 的组合,使得 x + y、x - y、y + z、y - z、x + z 和 x - z 是完全平方数

流和替代模型

emacs - Lisp:既未声明也未绑定(bind) CHAR

macros - 可以放心地忽略宏和内置宏之间的区别吗?

lisp - 复制时如何更新实体的扩展数据信息

jquery - "too much recursion"jquery错误

java - 如何将以下递归函数转换为 for 循环迭代

tree - 如何通过索引获取子树?