SICP-2.1.1节练习
SICP-2.1.3节练习

SICP-2.1.2节练习

lispor posted @ Feb 24, 2011 03:20:42 PM in Scheme with tags SICP , 1364 阅读

练习 2.2 - 2.3

 
练习 2.2:
Consider the problem of representing line segments in a plane. Each segment is represented as a pair
of points: a starting point and an ending point. Define a constructor make-segment and selectors
start-segment and end-segment that define the representation of segments in terms of
points. Furthermore, a point can be represented as a pair of numbers: the x coordinate and the y
coordinate. Accordingly, specify a constructor make-point and selectors x-point and y-point that
define this representation. Finally, using your selectors and constructors, define a procedure
midpoint-segment that takes a line segment as argument and returns its midpoint (the point whose
coordinates are the average of the coordinates of the endpoints). To try your procedures, you'll
need a way to print points:
(define (print-point p)
  (newline)
  (display "(")
  (display (x-point p))
  (display ",")
  (display (y-point p))
  (display ")"))
我的解答:
程序:
(define (make-point x y)
  (cons x y))

(define (x-point point)
  (car point))

(define (y-point point)
  (cdr point))

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

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

(define (start-segment segment)
  (car segment))

(define (end-segment segment)
  (cdr segment))

(define (midpoint-segment segment)
  (let ((start (start-segment segment))
        (end (end-segment segment)))
    (make-point (/ (+ (x-point start)
                      (x-point end))
                   2.0)
                (/ (+ (y-point start)
                      (y-point end))
                   2.0))))

运行结果:
scheme@(guile-user)> (define p1 (make-point 3 6))
scheme@(guile-user)> (define p2 (make-point 4 3))
scheme@(guile-user)> (define s (make-segment p1 p2))
scheme@(guile-user)> (print-point (midpoint-segment s))
(3.5,4.5)
 
练习 2.3:
Implement a representation for rectangles in a plane. (Hint: You may want to make use of Exercise
2-2.) In terms of your constructors and selectors, create procedures that compute the perimeter and
the area of a given rectangle. Now implement a different representation for rectangles. Can you
design your system with suitable abstraction barriers, so that the same perimeter and area
procedures will work using either representation?
我的解答:
(define (square x)
  (* x x))

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

(define (x-point point)
  (car point))

(define (y-point point)
  (cdr point))

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

(define (distance-points point1 point2)
  (let ((x1 (x-point point1))
        (y1 (y-point point1))
        (x2 (x-point point2))
        (y2 (y-point point2)))
    (sqrt (+ (square (- x2 x1))
             (square (- y2 y1))))))

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

(define (start-segment segment)
  (car segment))

(define (end-segment segment)
  (cdr segment))

(define (length-segment segment)
  (let ((start (start-segment segment))
        (end (end-segment segment)))
    (distance-points start end)))

(define (make-rect-1 base-segment height)
  (cons base-segment height))

(define (width-rect-1 rect)
  (let ((base-segment (car rect)))
    (length-segment base-segment)))

(define (height-rect-1 rect)
  (abs (cdr rect)))

(define (perimeter-rect-1 rect)
  (let ((height (height-rect-1 rect))
        (width (width-rect-1 rect)))
    (* 2 (+ width height))))

(define (area-rect-1 rect)
  (let ((height (height-rect-1 rect))
        (width (width-rect-1 rect)))
    (* width height)))

(define (make-rect-2 base-start base-end height)
  (cons base-start
        (cons base-end height)))

(define (width-rect-2 rect)
  (let ((start (car rect))
        (end (car (cdr rect))))
  (distance-points  start end)))

(define (height-rect-2 rect)
  (cdr (cdr rect)))

(define (perimeter-rect-2 rect)
  (let ((width (width-rect-2 rect))
        (height (height-rect-2 rect)))
    (* 2 (+ width height))))

(define (area-rect-2 rect)
  (let ((width (width-rect-2 rect))
        (height (height-rect-2 rect)))
    (* width height)))

(define (area-rect rect)
  (if (pair? (car (car rect)))
      (area-rect-1 rect)
      (area-rect-2 rect)))

(define (perimeter-rect rect)
  (if (pair? (car (car rect)))
      (perimeter-rect-1 rect)
      (perimeter-rect-2 rect)))


运行结果:
scheme@(guile-user)> (define p1 (make-point 3 6))
scheme@(guile-user)> (define p2 (make-point 3 9))
scheme@(guile-user)> (define s (make-segment p1 p2))
scheme@(guile-user)> (define rect1 (make-rect-1 s 6))
scheme@(guile-user)> (define rect2 (make-rect-2 p1 p2 6))
scheme@(guile-user)> (perimeter-rect rect1)
18.0
scheme@(guile-user)> (perimeter-rect rect2)
18.0
scheme@(guile-user)> (area-rect rect1)
18.0
scheme@(guile-user)> (area-rect rect2)
18.0

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter