简体   繁体   English

Scheme中的尾递归函数

[英]Tail recursive functions in Scheme

I'm studying for a Christmas test and doing some sample exam questions, I've come across this one that has me a bit stumped 我正在为圣诞节考试而学习,并做了一些样本考试题,我碰到了一个让我有些困惑的问题

题

I can do regular recursion fine, but I can't wrap my head around how to write the same thing using tail recursion. 我可以进行常规的递归,但是我无法用尾巴递归来写同样的东西。

Regular version: 普通版:

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

For a function to be tail recursive, there must be nothing to do after the function returns except return its value. 要使函数尾部递归,在函数返回后,除返回其值外,无需执行任何其他操作。 That is, the last thing that happens in the recursive step is the call to the function itself. 也就是说,在递归步骤中发生的最后一件事是对函数本身的调用。 This is generally achieved by using an accumulator parameter for keeping track of the answer: 这通常是通过使用累加器参数跟踪答案来实现的:

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

The above procedure will be initially called with 1 as accumulator, like this: 上面的过程将首先以1作为累加器来调用,如下所示:

(factorial 10 1)
=> 3628800

Notice that the accumulated value gets returned when the base case is reached, and that the acc parameter gets updated at each point in the recursive call. 注意,当达到基本情况时,将返回累加值,并且在递归调用的每个点上更新acc参数。 I had to add one extra parameter to the procedure, but this can be avoided by defining an inner procedure or a named let , for example: 我必须在过程中添加一个额外的参数,但是可以通过定义内部过程或命名的let来避免这种情况,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM