Схема нахождения среднего из списка - PullRequest
0 голосов
/ 03 декабря 2018

Итак, у меня есть код, который должен найти среднее значение списка, но я не вижу печатного значения в консоли

#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 голосов
/ 03 декабря 2018

sum и length каждый O (n) , что приводит к процессу O (2n) для average.Ниже мы покажем, как стиль передачи продолжения можно использовать для процесса average a 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
0 голосов
/ 03 декабря 2018

Ваш код имеет следующие проблемы:

  1. sum использовался до его определения.
  2. sum не принял параметр.
  3. *Функция 1010 * не была оценена в display.
  4. Я использовал 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))
0 голосов
/ 03 декабря 2018
(define (average l)
  (/ (foldr (lambda (x y) (+ x y)) 0 l) 
     (length l)))
0 голосов
/ 03 декабря 2018

Возможно, я использую другую версию схемы;https://scheme.cs61a.org/ - это компилятор, который я использую.Это сработало для меня, когда я включил параметр для функции sum следующим образом:

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

Надеюсь, это поможет!

...