我试图反向列出列表中元素的过度平均值,例如在(1 2 3)列表中我试图得到(3 + 2 + 1/3 2 + 1/2 1)这里是我尝试使用代码的列表示例。
(list 2 3 4 5 6)
由于某种原因,返回的值是" (4 7/2 4 7/2 4)"。这是代码
(define (sucessive-avg lst)
(if (=(length lst) 1)
lst
(cons(avg(reverse lst)) (sucessive-avg(cdr(reverse lst))))))
问题不是来自我的平均值所以我不知道它有什么问题
答案 0 :(得分:1)
你会拨多少次反向?尝试逐步执行代码以了解正在发生的事情。
您可以编写一个函数来收集列表的成功CDR的平均值,并使用反向列表调用它:
(define (successive-averages lst)
(if (null? lst)
lst
(cons (avg lst)
(successive-averages (rest lst))))
(successive-averages (reverse (list 2 3 4 5 6)))
答案 1 :(得分:0)
@ coredump的答案是一个非常好的开始,但它没有使用正确的尾递归,看起来它是平均列表的错误部分
例如在(1 2 3)列表中我试图得到(3 + 2 + 1/3 2 + 1/2 1)
有关'(2 3 4 5 6)
的列表,我的回答会给你
'((avg '(2 3 4 5 6))
(avg '(2 3 4 5))
(avg '(2 3 4))
(avg '(2 3))
(avg '(2)))
这似乎更准确地符合您的描述。
这是代码
(define (avg lst)
(/ (foldl + 0 lst)
(length lst)))
(define (successive-avg lst)
(define (iter res lst)
(if (empty? lst)
(reverse res)
(iter (cons (avg lst) res) (rest lst))))
(iter '() (reverse lst)))
(print (successive-avg '(2 3 4 5 6)))
输出
'(4 3 1/2 3 2 1/2 2)
答案 2 :(得分:0)
根本不需要回忆反向或平均值。你不需要平均值的原因是你可以保持一个运行总和(在我的代码中通过lambda链)和一个显式计数。并且感觉你首先想要最深的递归的结果,当你的recure给你正确的最终订单时,将平均值运行到累加器上。
(define (successiveAvg Lst)
(cond ((null? Lst)
(error "succesiveAvg requires a non-empty list"))
((fold (lambda (acc x)
(if acc (number? x) #f))
#t
Lst)
(error "succesiveAvg requires a list of numbers" Lst))
(else
(let ((inc (lambda (x)
(+ 1 x)))
(f (lambda (x)
(lambda (y) (+ x y)))))
(let loop ((acc '())
(c (lambda (x) x))
(L lst)
(i 1))
(if (null? L)
acc
(loop (cons (/ (c (car L)) i)
acc)
(f (c (car L)))
(cdr L)
(inc i))))))))
(successiveavg '(2 3 4 5 6))
;Value 3: (4 7/2 3 5/2 2)