昨天晚上读了2.1节,今天开始做下习题,这节相当有趣,数据抽象的概念解释的很清晰。
习题2.1,make-rat能正确地处理正负数,加几个判断条件即可:
习题2.2,首先定义make-point,x-point,y-point三个过程:
线段是由两点组成,在此基础上定义make-segment,start-segment,end-segment过程:
OK,然后定义题目要求的midpoint-segment求线段中间点坐标:
测试一下:
习题2.3,这题目主要是考察对过程抽象的理解,对于计算一个矩形的周长和面积来说,需要两个信息:长度和宽度。因此,首先假设我们已经有3个过程:make-rectang用于创建矩形,width用于返回宽,length用于返回长。那么周长和面积可以写为:
square过程就是平方过程,假设已经定义。
习题2.1,make-rat能正确地处理正负数,加几个判断条件即可:
(define (make-rate n d)
(let ((g (gcd n d)))
(cond ((or (and (negative? n) (positive? d)) (and (positive? n) (positive? d))) (cons (/ n g) (/ d g)))
(else
(cons (opposition (/ n g)) (opposition (/ d g)))))))
(let ((g (gcd n d)))
(cond ((or (and (negative? n) (positive? d)) (and (positive? n) (positive? d))) (cons (/ n g) (/ d g)))
(else
(cons (opposition (/ n g)) (opposition (/ d g)))))))
习题2.2,首先定义make-point,x-point,y-point三个过程:
(define (make-point x y) (cons x y))
(define (x-point p) (car p))
(define (y-point p) (cdr p))
(define (x-point p) (car p))
(define (y-point p) (cdr p))
线段是由两点组成,在此基础上定义make-segment,start-segment,end-segment过程:
(define (make-segment s e)
(cons s e))
(define (start-segment segment)
(car segment))
(define (end-segment segment)
(cdr segment))
(cons s e))
(define (start-segment segment)
(car segment))
(define (end-segment segment)
(cdr segment))
OK,然后定义题目要求的midpoint-segment求线段中间点坐标:
(define (midpoint-segment segment)
(let ((start (start-segment segment))
(end (end-segment segment)))
(make-point (/ (+ (x-point start) (x-point end)) 2) (/ (+ (y-point start) (y-point end)) 2))))
(let ((start (start-segment segment))
(end (end-segment segment)))
(make-point (/ (+ (x-point start) (x-point end)) 2) (/ (+ (y-point start) (y-point end)) 2))))
测试一下:
> (define start (make-point 10 10))
> (define end (make-point 0 0))
> (define segment (make-segment start end))
> (print-point (midpoint-segment segment))
(5,5)
> (define end (make-point 0 0))
> (define segment (make-segment start end))
> (print-point (midpoint-segment segment))
(5,5)
习题2.3,这题目主要是考察对过程抽象的理解,对于计算一个矩形的周长和面积来说,需要两个信息:长度和宽度。因此,首先假设我们已经有3个过程:make-rectang用于创建矩形,width用于返回宽,length用于返回长。那么周长和面积可以写为:
(define (perimeter rectang)
(* 2 (+ (width rectang) (length rectang))))
(define (area rectang)
(* (width rectang) (length rectang)))
具体如何实现make-rectang,width,length3个过程与周长、面积的计算实现了抽象隔离,具体实现的改变不需要修改 perimeter、area两个过程。矩形可以表示为一条有向线段和距离,有向线段是矩形的一条边,与它平行的另一条边的距离是d。因此定义下这三个过 程:
(* 2 (+ (width rectang) (length rectang))))
(define (area rectang)
(* (width rectang) (length rectang)))
(define (make-rectang segment d)
(cons segmeng d))
(define (length rectang)
(car rectang))
(define (width rectang)
(let ((seg (car x)))
(let ((s (start-segment seg))
(e (end-segment seg)))
(sqrt (+ (square (- (x-point s)
(x-point e)))
(square (- (y-point s)
(y-point e))))))))
(cons segmeng d))
(define (length rectang)
(car rectang))
(define (width rectang)
(let ((seg (car x)))
(let ((s (start-segment seg))
(e (end-segment seg)))
(sqrt (+ (square (- (x-point s)
(x-point e)))
(square (- (y-point s)
(y-point e))))))))
square过程就是平方过程,假设已经定义。