如何编写一个Scheme过程,该过程将列表和数字作为参数,并使用尾递归来计算并返回列表中所有数字的总和 从头开始直到遇到数字m的第一个实例? (如果从未遇到过,返回值将是所有元素的总和 在列表中。) 例如,(proc(list 1 2 3 4 5 6)4)应返回6。 我处理过程及其基本情况,即如果列表为空,则返回0.但是我需要另一个基本情况,当列表不包含作为参数给出的数字时,它返回列表元素的总和。
答案 0 :(得分:0)
因为这是作业,所以这次我不会给你一个直接的答案。以下是需要做什么的总体思路,填补空白:
(define (add-until lst num acc)
(if (or <???> ; if the list is null
(= <???> <???>)) ; or the current element equals `num`
acc ; then return the accumulator
(add-until ; else make a recursive call
<???> ; advance to the next element in list
num ; pass along the same `num`
(+ <???> <???>)))) ; update the accumulator with current element
如果在函数返回之后没有任何事情可做,除了返回它的值之外,函数调用被称为尾递归,正如您在上面的代码中所看到的,过程中的else
部分以调用结束add-until
之后没有别的事情要做了。
通常,累加器用于保存计算的部分结果,并且在递归的基本情况下返回结束。在示例中,累加器被称为acc
,并且在每次迭代时,其值都会更新,最后会返回。
当然,累加器需要以适当的值初始化。对于问题中的示例,这就是您调用add-until
过程的方式:
(add-until '(1 2 3 4 5 6) 4 0)
=> 6
或者,您可以定义两个过程 - 一个帮助器实现实际迭代并接收累加器作为参数(这是我上面概述的那个),另一个接收器只接收两个参数并始终调用辅助程序初始值为0
。
答案 1 :(得分:0)
ÓscarLópez的回答是正确的。以下是使用名为let
的相同代码的版本,(在我看来,至少)更容易阅读:
(define (add-until lst num)
(let loop ((lst lst)
(acc 0))
(if (or ???
(= ??? ???))
acc
(loop ??? (+ ??? ???)))))