Получение медианы 3 значений с использованием схемы - PullRequest
1 голос
/ 01 мая 2010

На этот раз проблема состоит в том, чтобы получить медиану из трех значений (просто)

Я сделал это:

(define (med x y z) (car(cdr(x y z)))

и это было принято, но при тестировании:

(med 3 4 5)

Я получаю эту ошибку:

Ошибка: попытка вызвать не процедуру
(2 3 4)

А при вводе букв вместо числа я получаю:

(md x y z)

Ошибка: неопределенная вариация
у
(пользователь пакета)

Используя что-то кроме x y z, я получаю:

(md d l m)

Ошибка: неопределенная переменная
д
(пользователь пакета)

вопрос был удален, не знаю как все равно

написать функцию, которая возвращает медиану из 3 значений

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

33> (define (med x y z)
   (if(and(

      (<x y) (<y z) y

               if(and(

                    (<y x) (<x z) x z)))))

Warning: invalid expression
         (if (and< (<x y) (<y z) y if (and ((<y x) (<x z) x z))))

но, как вы видите, я получаю предупреждение, так что же такое Wronge?

Ответы [ 3 ]

5 голосов
/ 01 мая 2010

Вы, вероятно, хотите создать список, например:

(define (med x y z) (car(cdr(list x y z)))

Однако кажется бесполезным объединять значения в список, чтобы снова отменить их. Это будет иметь тот же эффект:

(define (med x y z) y)
1 голос
/ 01 мая 2010

Обратите внимание, что, как определено, (med . rest) эквивалентно (cadr rest) (за исключением того, что med принимает только три значения). Лично я ожидал бы, что функция, которая должна возвращать медиану значений, вернет, ну, в общем, медиана , независимо от порядка в списке. Например, (med 4 2 5) вернет 4, а (3 0 9 6 5) вернет 5.

Что касается синтаксической ошибки (которая не имеет большого значения для написания med, поскольку есть лучший способ использования sort, length и list-ref), вы не ставьте свои скобки в правильных местах. Вот еще один способ написать то, что у вас есть сейчас, выстраивая термины с их братьями и сестрами и справа от их предков:

(if (and (
           (<x y) 
           (<y z) 
           y
           if
           (and (
                  (<y x) 
                  (<x z) 
                  x 
                  z
)   )    ) )    )

Формат if:

(if test-expr true-expr false-expr)

Все ваши условия являются подусловиями условного соглашения, и здесь нет true-expr или false-expr. Вы хотели бы написать свой код как:

(if (and ...)
    y
    (if (...) ; we know that (not (and (< x y) (< y z))
        x
        z))

Обратите внимание, что вы могли бы упростить последующие тесты, поскольку знаете, что предыдущие тесты являются ложными.

Вы также можете использовать cond, который более понятен, чем вложенная последовательность if s:

(cond (test result)
      (test result)
      (test result)
      ... )

Для вашего кода это будет:

(cond ((and ...) y)
      ((...) x)
      (else z))

В else нет ничего особенного (это скорее синтаксическая конструкция, чем выражение, не то чтобы она имела большое значение). Вместо этого вы можете использовать любое значение, которое оценивается как true (например, #t).

Помните, круглые скобки окружают как функцию, так и аргументы в Лиспе ((foo 1 2 3), а не foo(1, 2 ,3)), в отличие от математических обозначений, где круглые скобки окружают только аргументы.

0 голосов
/ 01 мая 2010

, хотя мы довольно хорошо объяснили проблему, есть еще один важный момент, который нужно знать

(<x y) 

вызывает функцию с именем

(< x y)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...