Схема — получение медианы из списка медиан из уже отсортированного списка

#list #scheme #median

#Список #схема #медиана

Вопрос:

Программа, которую я пытаюсь создать, — это программа, которая может выполнять ряд математических функций от average до std-dev и так далее, но та, на которой я спотыкаюсь, — это median. Список уже отсортирован, так как я могу получить длину этого списка, чтобы определить, четный или нечетный, а затем получить медиану из этого. Текущий код ниже. Довольно новичок в схеме, поэтому синтаксис меня все еще сбивает с толку.

код

 (define make-tswb
  (lambda ()
    (let ((records '()))
      (lambda (command . args)
        (cond
          ((equal? command 'empty?)
           (null? records))
          ((equal? command 'add!)
           (set! records (cons (car args) records)))
          ((equal? command 'get)
           (letrec ((sort-records (lambda (r) (sort r (lambda (x y) (<= (car x) (car y)))))))
             (if (null? args)
                 (sort-records records)
                 (sort-records (filter(car args) records)))))
          ((equal? command 'analytic)
           (cond
             ((= (length args) 1)
              ((car args) records))
             ((= (length args) 2)
              ((car args) (filter (cadr args) records))))))))))


(define listofVal
  (lambda (lst)
    (if (null? lst)
        '()
        (sort (map cadddr lst) <))))

(define median
  (lambda (medianList)
    (let ((values (listofVal medianList)))
      (let ((len (length medianList)))
      // ??????????


(define tswb (make-tswb))
(tswb 'add!     '(2 123 "temp1"  76.1))
(tswb 'add!     '(1 123 "temp1"  72.0))
(tswb 'add!     '(1 123 "temp1"  75.0))
(tswb 'analytic median)
 

Ответ №1:

Согласно этой странице, вам необходимо обработать два случая:

  1. Длина списка — четное число.
  2. Это не четное число.

Для первого случая вам нужно взять два значения в середине, посчитать их сумму, а затем разделить на два. Во втором случае вам нужно найти середину отсортированного списка, и это значение будет медианой.

Итак, я думаю, это должно сработать для вас:

 (define (count-median-for-even len listOfVal)
  (/ (  (list-ref listOfVal (round (- (/ len 2) 1)))
        (list-ref listOfVal (round (/ len 2)))) 2))

(define (count-median-for-odd len listOfVal)
  (list-ref listOfVal (round (/ len 2))))

(define median
  (lambda (medianList)
    (let ((values (listofVal medianList)))
      (let ((len (length medianList)))
        (if (even? len) (count-median-for-even len values) (count-median-for-odd len values))))))
 

Протестировав это на трех тестовых примерах по ссылке выше, я могу сказать, что это должно сделать работу за вас.