Fork me on GitHub

闭包:通过闭包组合起数据对象得到的结果本身还可以通过同样的操作再进行组合。

  (In general, an operation for combining data objects ststisfies the closure property if the results of combining things with that operation can themselves be combined using the same operation.)

序列(sequence):如图所示,序列由一个序对(pair)的链表(list)表示。每个序对的 car 部分对应于这个链中的条目, cdr 则是链中下一个序对。最后一个序对的 cdr 用一个不是序对的值表示,标明序列的结束。

基本过程:

1 (list <a1> ... <an>)
2 等价于
3 (cons <a1>
4       (cons ...
5                 (cons <an> nil) ... )))

基本谓词:

1 (pair? <argument>) ;检查其参数是否为序对

部分习题:

exercise 2.17

1 (define (last-pair items)    
2     (cond ((null? items) '())
3           ((null? (cdr items)) items)
4           (else (last-pair (cdr items)))))

 exercise 2.18

1 (define (reverse items)
2     (define (reverse-iter items result)
3         (if (null? items)
4             result
5             (reverse-iter (cdr items)
6                           (cons (car items) result))))
7     (reverse-iter items '()))

 exercise 2.19

 1 (define us-coins (list 50 25 10 5 1))
 2 (define uk-coins (list 100 50 20 10 5 2 1 0.5))
 3 (define (cc amount coin-values)
 4     (cond ((= amount 0) 1)
 5           ((or (< amount 0) (no-more? coin-values)) 0)
 6           (else (+ (cc amount
 7                        (except-first-denomination coin-values))
 8                    (cc (- amount 
 9                           (first-denomination coin-values))
10                        (coin-values)))))
11 (define (no-more? items)
12     (null? items))
13 (define (first-denomination items)
14     (car items))
15 (define (except-first-denomination items)
16     (cdr items))

exercise 2.20

 1 (define (get-item items filter)
 2     (if (null? items)
 3         '()
 4         (if (filter (car items))
 5             (cons (car items)
 6                   (get-item (cdr items) filter))
 7             (get-item (cdr items) filter))))
 8 (define (same-parity first . others)
 9     (cons first
10           (get-item others 
11                     (lambda (x) (even? (bitwise-xor first x)))))) 

 exercise 2.23

1 (define (for-each proc items)
2     (cond ((null? items) #t)
3           (else (proc (car items))
4                 (for-each proc (cdr items)))))

 exercise 2.26

 exercise 2.27

根据 reverse procedure 修改而来。

1 (define (deep-reverse x)
2     (define (deep-reverse-iter x result)
3         (cond ((null? x) result)
4               ((not (pair? x)) x)
5               (else (deep-reverse-iter (cdr x)
6                                        (cons (deep-reverse (car x))
7                                              result)))))
8     (deep-reverse-iter x '()))

 exercise 2.28

1 (define (not-pair? x)
2     (not (pair? x)))
3 (define (fringe x)
4     (define (iter x result)
5         (cond ((null? x) result)
6               ((not-pair? x) (cons x result))
7               (else (iter (car x)
8                           (iter (cdr x) result)))))
9     (iter x '()))

 章节2.2.3中的 enumerate-tree

1 (define (fringe tree)
2     (cond ((null? tree) '())
3           ((not (pair? tree)) (list tree))
4           (else (append (fringe (car tree))
5                         (fringe (cdr tree))))))

exercise 2.29

a) 选择函数

1 (define (left-branch mobile)
2     (car mobile))
3 (define (right-branch mobile)
4     (cadr mobile))
5 (define (branch-length branch)
6     (car branch))
7 (define (branch-structure branch)
8     (cadr branch))

 b) total-weight

 1 (define (total-weight mobile)
 2     (define (branch-iter branch)
 3         (if (not-pair? branch)
 4             branch
 5             (let ((structure (branch-structure branch)))
 6               (if (not-pair? structure)
 7                   structure
 8                   (total-weight structure)))))
 9     (if (not-pair? mobile); add this for balance procedure
10         mobile
11         (+ (branch-iter (left-branch mobile))
12            (branch-iter (right-branch mobile)))))

 c) balance?

 1 (define (balance? mobile)
 2     (define (moment branch)
 3         (if (not-pair? branch)
 4             0
 5             (let ((length (branch-length branch))
 6                   (weight (total-weight (branch-structure branch))))
 7               (* length weight))))
 8     (cond ((not-pair? mobile) #t)
 9           ((= (moment (left-branch mobile))
10               (moment (right-branch mobile)))
11            (balance-iter (branch-structure (left-branch mobile)))
12            (balance-iter (branch-structure (right-branch mobile))))
13            (else #f)))

 d) 用 list 和 cons 构造的不同在于, (cdr <list>) 的结果依然是一个 list,所以在选择函数 right-branch 中要用 cadr 才能得到正确的第二个元素,branch-structure 也是同样的道理。所以当构造方式由 list 变为 cons 时,只要修改以上提到的两个选择函数的实现就可以了。

exercise 2.30

 1 (define (square-tree tree)
 2     (cond ((null? tree) '())
 3           ((not (pair? tree)) (* tree tree))
 4           (else (cons (square-tree (car tree))
 5                       (square-tree (cdr tree))))))
 6 
 7 (define (square-tree tree)
 8     (map (lambda (sub-tree)
 9            (if (pair? sub-tree)
10                (square-tree sub-tree)
11                (* sub-tree sub-tree)))
12          tree))

 exercise 2.31

1 (define (tree-map proc tree)
2     (cond ((null? tree) '())
3           ((not (pair? tree)) (proc tree))
4           (else (cons (tree-map (car tree))
5                       (tree-map (cdr tree))))))
6 (define (square-tree tree)
7     (tree-map square tree)

 exercise 2.32

1 (define (subsets s)
2     (if (null? s)
3         '()
4         (let ((rest (subsets (cdr s))))
5           (append rest (map (lambda (x) (cons (car s) x))
6                             rest)))))
posted on 2012-11-09 23:33  sungoshawk  阅读(290)  评论(0编辑  收藏  举报