我正在为圣诞节考试而学习,并做了一些样本考试题,我碰到了一个让我有些困惑的问题
我可以进行常规的递归,但是我无法用尾部递归来写同样的东西。
普通版:
(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/