SICP 选用 Lisp 作为讨论程序设计的基础,考虑到的是 Lisp 的一个重要特征:计算过程的 Lisp 描述(即过程)本身又可以作为 Lisp 的数据来表示和操作。
一、程序设计的基本元素
每种强有力的语言都提供了三种机制:
- 基本表达形式:用于表示语言所关心的最简单的个体。
- 组合的方法:通过它们可以从较简单的东西出发构造出复合的元素。
- 抽象的方法:通过它们可以为复合对象命名,并将它们作为单元去操作。
1.1 表达式
(+ 21 35 12 7)
这种形式称为前缀表示
1.2 命名和环境
(define size 2)
define 是我们所用的语言里最简单的抽象方法。
1.3 过程应用的代换模型
- 正则序求值:完全展开而后规约
- 应用序求值:先求值参数而后应用
1.4 牛顿法求平方根
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
(define (improve guess x)
(average guess (/ x guess)))
(define (average x y)
(/ (+ x y) 2))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (square x)
(* x x))
(define (sqrt x)
(sqrt-iter 1.0 x))
1.5 练习1.6
二、过程与它们所产生的计算
2.1 练习1.11
迭代计算过程:
(define (fib n)
(fib-iter 2 1 0 n))
(define (fib-iter a b c n)
(if (< n 3)
a
(fib-iter (+ a
(* 2 b)
(* 3 c))
a
b
(- n 1))))
2.2 练习1.12
(define (Paska line row)
(cond ((> row line) 0)
((= row 1) 1)
((= row line) 1)
(else (+ (Paska (- line 1)
(- row 1))
(Paska (- line 1)
row)))))
2.3 练习1.16
(define (fast-expt b n)
(expt-iter b n 1))
(define (square b)
(* b b))
(define (expt-iter b n a)
(cond ((= n 0)
a)
((even? n)
(expt-iter (square b)
(/ n 2)
a))
((odd? n)
(expt-iter b
(- n 1)
(* b a)))))
2.4 练习1.18
(define (multi a b)
(multi-iter a b 0))
(define (multi-iter a b product)
(cond ((= b 0)
product)
((even? b)
(multi-iter (double a)
(halve b)
product))
((odd? b)
(multi-iter a
(- b 1)
(+ a product)))))
三、用高阶函数做抽象
2.1 过程作为参数
(define (sum-integers a b)
(if (> a b)
0
(+ a (sum-integers (+ a 1) b))))
(define (cube n)
(* n n n))
(define (sum term next a b)
(if (> a b)
0
(+ (term a)
(sum term next (next a) b))))
(define (inc n) (+ n 1))
(define (sum-cubes a b)
(sum cube inc a b))
2.2 练习1.29
(define (y k f a b n)
(f (+ a
(* k (/ (- b a) n)))))
(define (xinpushen f a b n)
(define (z k)
(+ (y k f a b n)
(* 4 (y (+ k 1) f a b n))
(y (+ k 2) f a b n)))
(define (xps-next n) (+ n 2))
(* (sum z xps-next 0 (- n 2))
(/ (/ (- b a) n) 3.0)))
2.3 练习1.30
(define (sum term a next b)
(define (iter a result)
(if (> a b)
result
(iter (next a)
(+ (term a) result))))
(iter a 0))
2.4 练习1.31
(define (product1 term next a b)
(if (> a b)
1
(* (term a)
(product1 term next (next a) b))))
(define (product2 term next a b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (* result (term a)))))
(iter a 1))
(define (factorial n)
(define (fac-term n)
(* (/ (- n 1) n)
(/ (+ n 1) n)))
(define (fac-next n)
(+ n 2))
(* (product2 fac-term fac-next 3.0 n)
4))
2.5 练习1.32
(define (accumulate1 combiner null-value term next a b)
(if (> a b)
null-value
(combiner (term a)
(accumulate1 combiner null-value (next a) b))))
(define (accumulate combiner null-value term next a b)
(define (iter a result)
(if (> a b)
result
(iter (next a) (combiner result (term a)))))
(iter a null-value))
2.6 练习1.33
(define (accumulate combiner null-value filter term next a b)
(define (ans a)
(if (filter a)
(term a)
null-value))
(if (> a b)
null-value
(combiner (ans a)
(accumulate combiner null-value filter term next (next a) b))))
(define (prime-sum a b)
(define (term a) a)
(define (next a) (+ a 1))
(accumulate + 0 prime? term next a b))
2.7 练习 1.37
阅读习题解答
(define (cont-frac n d k)
(define (iter s)
(if (= s k)
(d k)
(/ (n s) (+ (d s) (iter (+ s 1))))))
(iter 1))
(define (cont-frac N D k)
(define (iter i result)
(if (= i 0)
result
(iter (- i 1)
(/ (N i)
(+ (D i) result)))))
(iter k 0))
想法:
- 对于递归而言,由低次往高次计算,无须对算式进行转换,就是原本算式的计算顺序
- 对于迭代而言,由高次往低次计算,所以需要一个变量保存每次计算后的结果