在计划尾递归函数(Tail recursive functions in Scheme)

2019-07-04 09:24发布

我攻读圣诞节测试,并做一些样品的考题,我遇到这一个有我有点难倒

我可以做定期的递归很好,但我不能换我周围的头如何使用尾递归来写同样的事情。

普通版本:

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

Answer 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)))))


文章来源: Tail recursive functions in Scheme