在方案中添加列表元素

时间:2012-11-15 00:04:28

标签: scheme

如何编写一个Scheme过程,该过程将列表和数字作为参数,并使用尾递归来计算并返回列表中所有数字的总和 从头开始直到遇到数字m的第一个实例? (如果从未遇到过,返回值将是所有元素的总和 在列表中。) 例如,(proc(list 1 2 3 4 5 6)4)应返回6。 我处理过程及其基本情况,即如果列表为空,则返回0.但是我需要另一个基本情况,当列表不包含作为参数给出的数字时,它返回列表元素的总和。

2 个答案:

答案 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 ??? (+ ??? ???)))))