第二章 构造数据抽象
2.2 层次性数据和闭包性质
EX 2.33
accumulate中参数op是二元操作
lambda (x y) 中,x:(car seq) y:(accumulate op init (cdr seq))
1 2 3 4 5 6
| ;原始map定义 (define (map proc items) (if (null? items) '() (cons (proc (car items)) (map proc (cdr items)))))
|
1 2 3
| ;用accumulate定义 (define (map1 p sequence) (accumulate (lambda (x y) (cons (p x) y)) '() sequence))
|
1 2 3 4 5
| ;原始append定义 (define (append list1 list2) (if (null? list1) list2 (cons (car list1) (append (cdr list1) list2))))
|
1 2 3
| ;用accumulate定义 (define (append1 seq1 seq2) (accumulate cons seq2 seq1))
|
1 2 3 4 5 6
| ;原始length定义 (define (length items) (define (length-iter a count) (if (null? a) count (length-iter (cdr a) (+ 1 count)))))
|
1 2 3
| ;用accumulate定义 (define (length1 sequence) (accumulate (lambda (x y) (+ y 1)) 0 sequence))
|
EX 2.34
主要是采用Horner规则将多项式变形

1 2 3 4
| (define (horner-eval x coefficient-sequence) (accumulate (lambda (this-coeff higher-terms) (+ this-coeff (* higher-terms x))) 0 coefficient-sequence))
|
EX 2.35
1 2 3 4 5 6
| ;原始count-leaves定义 (define (count-leaves t) (cond ((null? t) 0) ((not (pair? t)) 1) (else (+ (count-leaves (car t)) (count-leaves (cdr t))))))
|
1 2 3 4 5 6 7 8 9
| ;用accumulate定义 ;map计算每一个结点的叶子数量,得到如(0 0 1 1 ......)的list,再累积便可 (define (count-leaves1 t) (accumulate + 0 (map (lambda (x) (if (pair? x) (count-leaves1 x) 1)) t)))
|
EX 2.36
重点在于如何得到每一个内部序列的第一个元素,于是map一次seqs,对每个内部序列都得到其car
1 2 3 4 5
| (define (accumulate-n op init seqs) (if (null? (car seqs)) '() (cons (accumulate op init (map car seqs)) (accumulate-n op init (map cdr seqs)))))
|
EX 2.37
1 2 3 4 5
| ;测试程序 矩阵1、2 向量1、2 (define test-matrix1 (list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9))) (define test-matrix2 (list (list 1 4 6) (list 2 5 7) (list 3 6 8) (list 4 6 9))) (define test-vector1 (list 1 2 3 4)) (define test-vector2 (list 4 5 6 6))
|
1 2 3
| ;求点积 (define (dot-product v w) (accumulate + 0 (map * v w)))
|
1 2 3 4 5
| ;矩阵乘向量,(矩阵列数 = 向量行数) 用map对每一行做点积 (define (matrix-*-vector m v) (map (lambda (row) (dot-product row v)) m))
|
1 2 3
| ;求转置矩阵 (define (transpose mat) (accumulate-n cons '() mat))
|
1 2 3 4 5 6 7 8
| ;矩阵相乘 (define (matrix-*-matrix m n) (let ((cols (transpose n))) (map (lambda (row) (map (lambda (col) (dot-product row col)) cols)) m)))
|
EX 2.38
书中fold-left过程如下
1 2 3 4 5 6 7
| (define (fold-left op initial sequence) (define (iter result rest) (if (null? rest) result (iter (op result (car rest)) (cdr rest)))) (iter initial sequence))
|
从右向左对元素使用op操作,类似于accumulate
1 2 3 4 5
| (define (fold-right op initial sequence) (if (null? sequence) initial (op (car sequence) (accumulate op initial (cdr sequence)))))
|
由几个例子可以看出,加法、乘法等满足结合律的op,对任何序列可以产生同样的结果
EX 2.39
1 2 3 4 5 6 7
| ;原始reverse (define (reverse x) (define (iter remain result) (if (null? remain) result (iter (cdr remain) (cons (car remain) result)))) (iter x '()))
|
1 2 3 4
| (define (reverse1 sequence) (fold-right (lambda (x y) (append y (list x))) '() sequence)) (define (reverse2 sequence) (fold-left (lambda (x y) (cons y x)) '() sequence))
|