Посередине сегмента


Из SICP:

Упражнение 2.2

Рассмотрим проблему представляя отрезков на плоскости. Каждый сегмент представлен в виде пары точек: начальная точка и конечную точку. Определить конструктор сделать-сегмента и селекторов старт-сегмента и конец сегмента, который определить представительство сегментов с точки зрения очков. Кроме того, точки могут быть представлены как пара числа: координаты X и y координат. Соответственно, указать сделать конструктор и селекторы X-точки и y-точки, которые определяют этот представление. Наконец, используя свой селекторы и конструкторы, определить процедуры серединного сегмента, который занимает сегмент линии в качестве аргумента и возвращает его середину (точка которого координаты среднего координаты крайних точек). Чтобы попробовать ваши процедуры, вам нужен способ, чтобы точек печати:

(define (print-point p)
  (newline)
  (display "(")
  (display (x-point p))
  (display ",")
  (display (y-point p))
  (display ")"))

Я написал следующее решение:

(define (make-segment a b) (cons a b))
(define (start-segment l) (car l))
(define (end-segment l) (cdr l))

(define (make-point x y) (cons x y))
(define (x-point p) (car p))
(define (y-point p) (cdr p))

(define (sum . l) (if (zero? (length l)) 0 (+ (car l) (apply sum (cdr l)))))
(define (average . l) (/ (apply sum l) (length l)))

(define (midpoint seg)
  (make-point (average (x-point (start-segment seg)) 
                       (x-point (end-segment seg)))
              (average (y-point (start-segment seg))
                       (y-point (end-segment seg)))))

(define (print-point p)
  (newline)
  (display "(")
  (display (x-point p))
  (display ",")
  (display (y-point p))
  (display ")"))

(define seg-1 (make-segment (make-point 3 4)
                            (make-point 8 10)))
(print-point (midpoint seg-1))

Что вы думаете?



569
2
задан 1 апреля 2011 в 04:04 Источник Поделиться
Комментарии
1 ответ

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

(define make-segment cons)
(define start-segment car)
(define end-segment cdr)

(define make-point cons)
(define x-point car)
(define y-point cdr)

Ваше определение суммы, подобно тому, как + работает. Вы можете использовать + вместо в определении средних.

(define (average . l) (/ (apply + l) (length l)))

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

(define point->coordinate-accessors (list x-point y-point))
(define (midpoint seg)
(apply make-point (map (lambda (point->coordinate)
(average (point->coordinate (start-segment seg))
(point->coordinate (end-segment seg))))
point->coordinate-accessors)))

Этого определения достаточно, чтобы обрабатывать медианы расчет в столько размеры, как обрабатывается делают-точка и точка->координатно-аксессоры.

2
ответ дан 1 апреля 2011 в 07:04 Источник Поделиться