【SICP练习】44 练习2.3



练习2.3

我们并不必急于写出点什么,先来回过头看看书吧。第56页说到了一种称为按愿望思维的强有力的综合策略。在这道题里,我们就可以假设已经写好了能够表示矩形的代码,以及能够求矩形长和宽的函数。

于是像先定义出add-rat一样,我们先定义出求矩形的周长和面机的函数。

(define(get-perimeter x)

(let ((length (rectangle-length x))

    (width (rectangle-width x)))

  (* 2 (+ length width))))

(define(get-area x)

     (* (rectangle-length x) (rectangle-widthx)))

啊哈,书上要求用2中方式来表示矩形。我先来说说比较难看的一种表示方式,我一开始想到的下面那一种。

(define(make-ractangle rec-length-1 rec-length-2 rec-width-1 rec-width-2)

   (cons (cons rec-length-1 rec-length-2)

         (cons rec-width-1 rec-width-2)))

(define(rec-len-1 x)

   (car (car x))

(define(rec-len-2 x)

   (cdr (car x))

(define(rec-wid-1 x)

   (car (cdr x))

(define(rec-wid-2 x)

   (cdr (cdr x))

如书上所说,我们还要加载一下练习2.2中的代码。然后我们就可以开始构造矩形了。

(definelen-1 (make-segment (make-point 0 0)

                             (make-point 5 0)))

(definelen-2 (make-segment (make-point 0 4)

                             (make-point 5 4)))

(definewid-1 (make-segment (make-point 0 0)

                             (make-point 0 4)))

(definewid-2 (make-segment (make-point 5 0)

                             (make-point 5 4)))

(definerectangle-first (make-rectangle len-1 len-2 wid-1 wid-2))

这样打印出来的肯定是很混乱的,估计是一大堆括号的嵌套。所以还是要想书中那样自己写一个打印的函数。这里也要加载前面的print-point函数。

(define(print-rec x)

   (let ((l1 (len-1 x))

        (l2 (len-2 x))

        (w1 (wid-1 x))

        (w2 (wid-2 x)))

       (newline)

(display “Length-1: “)

(print-point (start-segment l1))

(print-point (end-segment l1))

(newline)

(display “Length-2: “)

(print-point (start-segment l2))

(print-point (end-segment l2))

(newline)

(display “Width-1: “)

(print-point (start-segment w1))

(print-point (end-segment w1))

(newline)

(display “Width-1: “)

(print-point (start-segment w2))

(print-point (end-segment w2))

现在打印出来的就比较直观了。

(print-rec rectangle-first)

Length-1:

(0,0)

(5,0)

Length-2:

(0,4)

(5,4)

Width-1:

(0,0)

(0,4)

Width-2

(5,0)

(5,4)

下面我们还需要函数来计算长和宽。

(define (get-length x)

       (let((length (len-1 x)))

     (let ((start (start-segment length))

           (end (end-segment length)))

       (- (x-point end) (x-point start)))))

(define (get-width x)

       (let((width (wid-1 x)))

     (let ((start (start-segment width))

           (end (end-segment width)))

       (- (y-point end) (y-point start)))))

下面就可以来计算长和宽了,试试吧。

(get-perimeter rectangle-first)

;Value: 18

(get-area rectangle-fist)

;Value: 20

这种方式真是麻烦,谁会一开始想到这种呢,还是用两条线段简单啊,反正是矩形又不是菱形。

(define (make-ractangle length width)

   (cons length width))

(define (rec-len x)

   (car x))

(define (rec-wid x)

   (cdr x))

(define (get-length x)

       (let((length (rec-len x)))

     (let ((start (start-segment length))

           (end (end-segment length)))

       (- (x-point end) (x-point start)))))

(define (get-width x)

       (let((width (rec-wid x)))

     (let ((start (start-segment width))

           (end (end-segment width)))

       (- (y-point end) (y-point start)))))

现在来创建矩形也很简单了。

(define len (make-segment (make-point 00)

                          (make-point 5 0)))

(define wid (make-segment (make-point 00)

                           (make-point 4 0)))

(define rectangle-second(make-rectangle len wid))

你可能感兴趣的:(SICP)