在Scheme中查找嵌套列表的总体平均值?

时间:2010-11-02 15:52:22

标签: scheme

嘿伙计们,我正在使用MIT Scheme并尝试编写一个程序来查找一堆嵌套列表中所有数字的平均值,例如:

(average-lists (list 1 2 (list 3 (list 4 5)) 6)))

应该返回3.5。我已经玩了几天以下的代码了,现在我已经得到它返回总和,但不是平均值。此外,重要的是首先计算最内部列表的值,因此不提取所有值并简单地对它们求平均值。

这是我到目前为止所拥有的:

(define (average-lists data)
  (if (null? data)
      0.0
      (if (list? (car data))
            (+ (average-lists (car data)) (average-lists (cdr data)))
            (+ (car data) (average-lists (cdr data))))))

我尝试过这种方法,并尝试使用map递归地将lambda函数映射到它,还有其他一些,但我找不到一个。我认为我的事情比现在更难。

我写了以下内容,努力追求其他一些路径,你可能会发现它们很有用:

(define (list-num? x)    ;Checks to see if list only contains numbers
  (= (length (filter number? x)) (length x)))

(define (list-avg x)     ;Returns the average of a list of numbers
  (/ (accumulate + 0 x) (length x)))

非常感谢您的帮助!这个问题对我来说是个噩梦。 :)

2 个答案:

答案 0 :(得分:3)

(define (flatten mylist)
  (cond ((null? mylist) '())
        ((list? (car mylist)) (append (flatten (car mylist)) (flatten (cdr mylist))))
        (else (cons (car mylist) (flatten (cdr mylist))))))


(define (myavg mylist)
  (let ((flatlist (flatten mylist)))
    (/ (apply + flatlist) (length flatlist))))

第一个函数展平列表。也就是说,它会将'(1 2 (3 (4 5)) 6)转换为'(1 2 3 4 5 6) 然后只需将+应用于平面列表并进行平均。

  

第一个功能的参考:   http://www.dreamincode.net/code/snippet3229.htm

答案 1 :(得分:3)

除非参数另有要求,否则您需要定义一个辅助程序,该程序可以计算每个列表中有多少项的总和计数。一旦您可以对单个列表求平均值,就可以通过检查car是否为列表来轻松地将其调整为嵌套列表。

此方法将获得列表中一次传递的平均值,而不是两次或多次传递解决方案,这些传递使列表变平或执行计数以及两次单独传递中的总和。你必须得到总和并与子列表分开计算才能获得总体平均值(参见下面的zinglon评论)。

修改

获得总和和计数的一种方法是将其传回一对:

(define sum-and-count  ; returns (sum . count)
  (lambda (ls) 
   (if (null? ls)
       (cons 0 0)
       (let ((r (sum-and-count (cdr ls))))
         (cons (+ (car ls) (car r))
               (add1 (cdr r)))))))

该过程获取列表元素的总和和数量。对你自己average-lists做了什么,让它来检查深层嵌套列表。然后,您可以通过(/ (car result) (cdr result))获得平均值。

或者,您可以编写单独的deep-sumdeep-count程序,然后执行(/ (deep-sum ls) (deep-count ls)),但这需要在列表上进行两次传递。