; ======================================================================
;
; Structure and Interpretation of Computer Programs
; (trial answer to excercises)
;
; 计算机程序的构造和解释(习题试解)
;
; created: code17 07/28/05
; modified:
; (保持内容完整不变前提下,可以任意转载)
; ======================================================================
;; SICP No.2.29
;; a.
(define (left-branch m) (car m))
(define (right-branch m) (car (cdr m)))
(define (
branch-length b) (car b))
(define (
branch-structure b) (car (cdr b)))
;; b.
(define (
branch-weight b)
(let ((bs (
branch-structure b)))
(if (pair? bs)
(total-weight bs)
bs)))
(define (total-weight m)
(+ (
branch-weight (left-branch m))
(
branch-weight (right-branch m))))
;; c.
(define (balanced? m)
(if (pair? m)
(let ((lb (left-branch m))
(rb (right-branch m)))
(and (balanced? (
branch-structure lb))
(balanced? (
branch-structure rb))
(= (* (
branch-weight lb) (
branch-length lb))
(* (
branch-weight rb) (
branch-length rb)))))
;; d.
;; 抽象数据类型的对外界的行为仅决定于其algebraic specification:
;; 在这里即为constructor和selector函数间的代数关系
;; 因此只需要修改对应selector函数即可,其他函数均建立在它们之上,因此不受影响。
;;
;; 在上述程序中有两处使用(pair? x)来判断该structure是number还是另一个mobile,
;; 这是底层数据类型相关的,因此最好是提供一个具体实现无关的函数mobile?来代替,
;; 比如: (define (mobile? x) (pair? x))
;; 当底层数据结构改变则重新定义mobile?。
;; (注意,此定义以及程序中的许多判断函数定义仅在无类型错误的前提下成立,
;; 这是因为原题中所有的constructor和selector函数定义均未对输入数据的类型作检查,
;; 因此我们也缺省假定不必考虑类型错误的情况)
;; Test-it:
;; Welcome to MzScheme version 209, Copyright (c) 2004 PLT Scheme, Inc.
;; > (define m1
;; (make-mobile (make-branch 20 (make-mobile (make-branch 10 4)
;; (make-branch 20 2)))
;; (make-branch 40 3)))
;; > m1
;; ((20 ((10 4) (20 2))) (40 3))
;; > (total-weight m1)
;; 9
;; > (balanced? m1)
;; #t