试图这样做 '(3 2 1)
->.用累积递归的方法,我可以得到我想要的结果(算是)。'(6 3 1)
通过累积递归,我可以得到我想要的结果(某种程度上),我的意思是,我的首字母和尾字母似乎是按正确的顺序排列的,但我的 (cons
希望有一个列表,我给它一个数字。希望得到任何帮助。
如果我把 (cons
与 (list
在助手和我 (reverse
的 li
函数中的变量,我得到的是 '(6 3 1)
我想,但 (list (list (list '()
在前面。我只是想 '(6 3 1)
这是我所拥有的
(define (subtotal li)
(subtotal-help (reverse li) 0))
(define (subtotal-help li acc)
(cond
[(empty? li) empty]
[else (list (subtotal-help (rest li)
(+ (first li) acc))
(+ (first li) acc))]))
你应该使用 cons
来建立一个输出列表,而不是 list
. 你的代码已经接近正确了,我们只需要调整一下位置,并增加一个额外的 reverse
在最后。
(define (subtotal li)
(reverse
(subtotal-help (reverse li) 0)))
(define (subtotal-help li acc)
(cond
[(empty? li) empty]
[else (cons (+ (first li) acc)
(subtotal-help (rest li) (+ (first li) acc)))]))
但如果你真的想要一个尾部递归的解决方案 那就需要更多的工作了。
(define (subtotal li)
(cond
[(empty? li) empty]
[else (let ((lst (reverse li)))
(subtotal-help (rest lst) (list (first lst))))]))
(define (subtotal-help li acc)
(cond
[(empty? li) acc]
[else (subtotal-help (rest li)
(cons (+ (first li) (first acc))
acc))]))
不管是哪种方法,都能达到预期的效果
(subtotal '(3 2 1))
=> '(6 3 1)
@ÓscarLópez的回答很好地回答了OP的直接问题 但还有其他的方法可以解决这个问题 但这可能不是OP的教授想要的
我们可以 map
在输入的列表上加上一系列的索引,使用 drop
以减少每个 apply
其余的列表汇总。在此 _x
是指通过以下方式从输入列表中获取的(被忽略的)值。map
, n
是指元素的数量 drop
和 xs
是输入列表。
(define (subtotal-list xs)
(map (lambda (_x n)
(apply + (drop xs n)))
xs
(range (length xs))))
scratch.rkt> (subtotal-list '(3 2 1))
'(6 3 1)
scratch.rkt> (subtotal-list '())
'()
顺便说一下,Common Lisp有一个很好的成语来形容这种事情,它的工作原理类似于使用 LOOP
宏。喏 x
不使用列表中的元素 xs
列表,而是整个列表,并且在每次迭代时 x
通过使用 cdr
(默认情况下)。
(defun subtotal-list-cl (xs)
(loop
:for x :on xs
:collect (apply #'+ x)))
SCRATCH> (subtotal-list-cl '(3 2 1))
(6 3 1)
SCRATCH> (subtotal-list-cl '())
NIL
回到手头的任务,如果需要一个迭代帮助程序,以及如果: apply
允许,那么可以定义一个更简洁的尾部递归过程的版本。这里,由于中间结果是 cons
蓄能器的前端,蓄能器的末端必须反转。
(define (subtotal-list-iter xs)
(subtotal-list-helper xs '()))
(define (subtotal-list-helper xs acc)
(if (null? xs) (reverse acc)
(subtotal-list-helper (rest xs)
(cons (apply + xs) acc))))
scratch.rkt> (subtotal-list-iter '(3 2 1))
'(6 3 1)
scratch.rkt> (subtotal-list-iter '())
'()