我试图弄清楚如何将3个变量合并到我的尾部递归代码中

问题描述 投票:1回答:2

编写一个名为popadd的尾递归函数,该函数在时间t = 0时为具有P个人的人群建模,并且每年增加d个人。

(define (popadd t  P)
  (if (= t 0)
      P
  (+(popadd( - t 1) P)d)) 
)

但是,当然,我得到了d尚未定义的错误,这是真的。我尝试将其添加为输入,但作为返回,我得到为D插入的数字。

scheme lisp racket
2个回答
3
投票

您可以简单地将另一个参数传递给递归:

(define (popadd t P d)
  (if (= t 0)
      P
      (+ d (popadd (- t 1) P d))))

或者您可以定义值,以避免传递它 - 假设它不需要更改:

(define d 100)

(define (popadd t P)
  (if (= t 0)
      P
      (+ d (popadd (- t 1) P))))

请注意,如果没问题,你可以对P做同样的事情。这实际上取决于程序的预期合同。


2
投票

请注意,您的代码和其他答案中的代码都不是尾递归的:在像(+ (f ...))这样的递归调用中,f不在尾部位置。要使代码尾递归,您需要递归调用的结果是整个调用的结果(因此在上面的示例中,+处于尾部位置)。要做到这一点,你需要一个辅助功能。这是一种只依赖于本地define的方法:

(define (popadd t P d)
  (define (popadd-loop tau pop)
    (if (zero? tau)
        pop
        (popadd-loop (- tau 1) (+ pop d))))
  (popadd-loop t P)) 

这与使用named-let基本相同,这更好:

(define (popadd t P d)
  (let popadd-loop ([tau t] [pop P])
    (if (zero? tau)
        pop
        (popadd-loop (- tau 1) (+ pop d)))))

最后请注意,此问题有一个封闭形式的解决方案:

(define (popadd t P d)
  (+ P (* t d)))

我真的希望那些试图教编程的人知道足够的数学,不能设置具有微不足道的封闭形式答案的问题,因为这样做会鼓励人们编写低效(在复杂性级别的意义上)代码。显然这不是你的错:这是你老师的。

© www.soinside.com 2019 - 2024. All rights reserved.