编写一个名为popadd的尾递归函数,该函数在时间t = 0时为具有P个人的人群建模,并且每年增加d个人。
(define (popadd t P)
(if (= t 0)
P
(+(popadd( - t 1) P)d))
)
但是,当然,我得到了d尚未定义的错误,这是真的。我尝试将其添加为输入,但作为返回,我得到为D插入的数字。
您可以简单地将另一个参数传递给递归:
(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
做同样的事情。这实际上取决于程序的预期合同。
请注意,您的代码和其他答案中的代码都不是尾递归的:在像(+ (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)))
我真的希望那些试图教编程的人知道足够的数学,不能设置具有微不足道的封闭形式答案的问题,因为这样做会鼓励人们编写低效(在复杂性级别的意义上)代码。显然这不是你的错:这是你老师的。