Медианная процедура схемы MIT

Как бы вы определили процедуру поиска медианы списка без использования list-ref? Например, (median '(1 2 2)) вернет 2, а (median '(1 2 3 4 5 6)) вернет 3,5. Можно предположить, что это список отсортированных целых чисел.

Это вопрос домашнего задания, поэтому, пожалуйста, не публикуйте фактический код. Все, что я ищу, это какие-то подсказки или какой-то псевдокод, который поможет мне двигаться в правильном направлении. Как указано в заголовке, я использую схему MIT. Заранее спасибо.


person Alex    schedule 16.03.2013    source источник


Ответы (2)


Вы знаете, как использовать алгоритм черепахи и зайца? Если да, то после завершения алгоритма ваша черепаха окажется в середине списка.

Если вы действительно застряли, у меня есть работающая реализация. Или вот что-то похожее на псевдокод:

(define (median lst)
  (if (null? lst) #f                         ;; oops, empty list
      (let loop ((tortoise <???>)
                 (hare <???>))
        (cond ((eq? tortoise hare) #f)       ;; oops, circular list
              ((null? hare) <???>)           ;; median value here
              ((null? (cdr hare)) <???>)     ;; average of middle two elements
              (else (loop <???> <???>))))))  ;; keep going
person Chris Jester-Young    schedule 16.03.2013
comment
Немного поиграв, я заработал. Большое спасибо! - person Alex; 16.03.2013

В случае, когда медиана является средним значением двух средних элементов в списке, использование list-ref будет неэффективным. Причина в том, что вам придется дважды пропустить первую половину списка, чтобы найти два средних элемента.

Одним из решений является написание вспомогательной функции (drop-list a-list n), которая удаляет первые n элементов списка. Например. (drop-list '(a b c d e) 2) это '(c d e). Теперь с помощью drop-list вы можете сделать следующее:

  1. Найдите длину списка
  2. Если длина нечетная, используйте list-ref для выбора среднего элемента.
  3. Если длина четная, используйте раскрывающийся список, чтобы удалить элементы перед двумя средними элементами, а затем вычислите среднее значение первых двух элементов результата.
person soegaard    schedule 16.03.2013
comment
Я думаю, что в качестве домашнего задания запрет на использование list-ref не столько для эффективности, сколько для демонстрации понимания алгоритма черепахи и зайца. :-) - person Chris Jester-Young; 17.03.2013
comment
Трудно сказать, не зная материала, который они изучили на уроке. - person soegaard; 18.03.2013