方案查找列表的平均值

时间:2018-12-03 04:39:33

标签: scheme racket

所以我有一些代码可以找到列表的平均值,但是在控制台中看不到任何打印值

#lang racket
(define x (list '10 '60 '3 '55 '15 '45 '40))
(define (average x)
(/ (sum x) (length x)))

(display average (current-output-port))

(define (sum)
(if (null? x)
    0
    (+ (car x) (sum (cdr x)))))

它只是显示

#<procedure:average>

4 个答案:

答案 0 :(得分:3)

您的代码存在以下问题:

    在定义之前使用
  1. sum
  2. sum没有使用参数。
  3. average中未评估
  4. display函数。
  5. 我使用exact->inexact是因为我认为这是您的意图。

以下作品。

(define x (list 10 60 3 55 15 45 40))

(define (sum x)
    (if (null? x)
        0
        (+ (car x) (sum (cdr x)))))

(define (average x)
    (/ (sum x) (length x)))

(display (exact->inexact (average x)) (current-output-port))

答案 1 :(得分:1)

(define (average l)
  (/ (foldr (lambda (x y) (+ x y)) 0 l) 
     (length l)))

答案 2 :(得分:1)

sumlength均为 O(n),导致average O(2n)处理。下面我们展示了如何通过延续传递样式来使average成为 O(n)进程。

(define (average xs (return /))
  (if (empty? xs)
      (return 0 0)
      (average (cdr xs)
               (lambda (sum len)
                 (return (+ sum (car xs))
                         (+ len 1))))))

(printf "~a~n" (average '(10 60 3 55 15 45 40)))
;; 228/7

exact->inexact中使用average意味着只能返回不精确的结果。使用不精确的数字进行其他计算会导致其他不精确。您可能会认为inexact->exact可以逆转其中任何一个,但是只能近似。

(average '(10 60 3 55 15 45 40)
;; 32 4/7

(inexact->exact (exact->inexact (average '(10 60 3 55 15 45 40))))
;; 32 40210710958665/70368744177664

因此,通常只在显示之前将精确数字转换为不精确的数字是有意义的。

(printf "~a\n" (exact->inexact (average '(10 60 3 55 15 45 40))))
;; 32.57142857142857

给出空列表时,我们的平均过程也会引发错误。

(average '())
;; error /: division by zero

或者,我们可以使用命名的let表达式来写平均值。还有 O(n)

(define (average xs)
  (let loop ((xs xs)
             (sum 0)
             (len 0))
    (if (empty? xs)
        (/ sum len)
        (loop (cdr xs)
              (+ sum (car xs))
              (+ len 1)))))

(average '(10 60 3 55 15 45 40)
;; 32 4/7

答案 3 :(得分:0)

我可能正在使用不同版本的方案; https://scheme.cs61a.org/是我使用的编译器。当我为函数sum包含一个参数时,它对我有用:

(define (sum x)
  (if (null? x)
    0
    (+ (car x) (sum (cdr x)))))

希望这会有所帮助!