我正在为圣诞节考试而学习,并做了一些样本考试题,我碰到了一个让我有些困惑的问题

我可以进行常规的递归,但是我无法用尾部递归来写同样的东西。

普通版:

    (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/

10-11 22:08
查看更多