方案列出了反向的过度平均值

时间:2015-11-06 13:44:40

标签: list recursion scheme

我试图反向列出列表中元素的过度平均值,例如在(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))))))

问题不是来自我的平均值所以我不知道它有什么问题

3 个答案:

答案 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)