Scheme 累积递归函数,用于生成从最后一个到第一个小计的列表
尝试使用累积递归执行此操作(3 2 1)->Scheme 累积递归函数,用于生成从最后一个到第一个小计的列表,scheme,racket,Scheme,Racket,尝试使用累积递归执行此操作(3 2 1)->'(6 3 1) 我可以得到我想要的结果(某种程度上),我的意思是我的第一次和休息似乎顺序正确,但我的(cons需要一个列表,我会给它一个数字。任何帮助都将不胜感激 如果我在助手中用(list)替换(cons,在函数中用(reverse替换)li变量,我会得到我想要的(631),但是前面有(list)(list)(list')。我只想要(631) 这就是我所拥有的 (define (subtotal li) (subtotal-help (reve
'(6 3 1)
我可以得到我想要的结果(某种程度上),我的意思是我的第一次和休息似乎顺序正确,但我的(cons
需要一个列表,我会给它一个数字。任何帮助都将不胜感激
如果我在助手中用(list
)替换(cons
,在函数中用(reverse
替换)li
变量,我会得到我想要的(631)
,但是前面有(list)(list)(list')
。我只想要(631)
这就是我所拥有的
(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-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))))
但是如果您真的想要一个尾部递归解决方案,那么需要做更多的工作:
(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)
您应该使用
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-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))))
但是如果您真的想要一个尾部递归解决方案,那么需要做更多的工作:
(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的教授可能并不完全想要解决这个问题 您可以
将输入列表和一系列索引映射到列表中,使用拖放减少每个应用的列表,该列表将剩余列表相加。此处\u x
是(忽略的)map
从输入列表中获取的值,n
是要drop
的元素数,xs
是输入列表:
(define (subtotal-list xs)
(map (lambda (_x n)
(apply + (drop xs n)))
xs
(range (length xs))))
scratch.rkt>(小计列表(3 2 1))
'(6 3 1)
scratch.rkt>(小计列表'())
'()
顺便说一句,Common Lisp有一个很好的习惯用法,它使用循环
宏类似地工作。这里x
不是从列表xs
中获取元素,而是从整个列表中获取元素,并且在每次迭代时x
都会通过使用cdr
来减少(默认情况下):
SCRATCH>(分类汇总表cl'(3 2 1))
(6 3 1)
草稿>(小计列表cl'())
无
回到手头的作业,如果需要迭代辅助程序,并且允许使用apply
,则可以定义更简洁的尾部递归程序版本。在这里,由于中间结果cons
放在累加器的前面,累加器必须在末尾反转:
(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-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>(国际热核实验堆(iter)(3 2 1)小计清单)
'(6 3 1)
scratch.rkt>(iter'()小计列表)
'()
斯卡尔洛佩斯的好答案回答了OP的直接问题,但有其他方法来解决这个问题,而OP的教授可能并不完全想要解决这个问题
您可以将输入列表和一系列索引映射到列表中,使用拖放减少每个应用的列表,该列表将剩余列表相加。此处\u x
是(忽略的)map
从输入列表中获取的值,n
是要drop
的元素数,xs
是输入列表:
(define (subtotal-list xs)
(map (lambda (_x n)
(apply + (drop xs n)))
xs
(range (length xs))))
scratch.rkt>(小计列表(3 2 1))
'(6 3 1)
scratch.rkt>(小计列表'())
'()
顺便说一句,Common Lisp有一个很好的习惯用法,它使用循环
宏类似地工作。这里x
不是从列表xs
中获取元素,而是从整个列表中获取元素,并且在每次迭代时x
都会通过使用cdr
来减少(默认情况下):
SCRATCH>(分类汇总表cl'(3 2 1))
(6 3 1)
草稿>(小计列表cl'())
无
回到手头的作业,如果需要迭代辅助程序,并且允许使用apply
,则可以定义更简洁的尾部递归程序版本。在这里,由于中间结果cons
放在累加器的前面,累加器必须在末尾反转:
(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-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>(国际热核实验堆(iter)(3 2 1)小计清单)
'(6 3 1)
scratch.rkt>(iter'()小计列表)
'()
在这里使用累加器有什么意义?小计帮助
不在尾部位置,因此此代码不是一个迭代过程。您可以使用应用
?@exnihilo这是一个课堂问题。教授想要一个累加器式的帮助函数。我应该将0添加到1,1添加到2,2添加到3,然后生成列表。我是new到programming@exnihilo有一点。教授到处都是,随着校园的关闭,课堂是在线的。因此,他更让人困惑,因为他没有教任何新的东西。我认为先叫小计意味着它处于尾声。我必须做更多的研究。我几乎是在自学。@exnihilo The accumulator用于跟踪总和,而不是输出列表。我认为不需要编写尾部递归解决方案。@JezzLess我不确定“累积递归”是什么意思。是“尾部递归”吗?如果这是一个要求,那么看看我的第二个解决方案。否则使用第一个解决方案在这里使用累加器有什么意义?小计帮助
不在尾部位置,因此此代码不是一个迭代过程。你能用应用
?@exnihilo吗?这是一个课堂问题。教授想要一个累加器式的帮助程序函数。我应该将0添加到1,1添加到2,2添加到3,然后生成列表。我是新手programming@exnihilo有一点。教授到处都是,随着校园的关闭,课堂是在线的。因此,他更加困惑,因为他没有