0

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

4

2 回答 2

0

Óscar López 的回答是正确的。这是相同代码的一个版本,使用命名let,即(在我看来,至少)更易于阅读:

(define (add-until lst num)
  (let loop ((lst lst)
             (acc 0))
    (if (or ???
            (= ??? ???))
        acc
        (loop ??? (+ ??? ???)))))
于 2012-11-15T01:58:44.880 回答
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

于 2012-11-15T00:47:09.200 回答