SICP阅读笔记[第一章]
习题部分
习题1.2 中缀表达式转为前缀表达式
(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5)))))
(* 3 (- 6 2) (- 2 7))
)
习题1.3 定义一个过程,返回三个数中较大两者的和
;返回两个数中的较大者
(define (max_of_two a b)
(if (> a b)
a
b))
;返回三个数中的较大者
(define (max_of_three a b c)
(max_of_two (max_of_two a b)
(max_of_two a c)))
;返回三个数中较大两者的和
(define (max_pair_of_three a b c)
(max_of_three (+ a b) (+ a c) (+ b c)))
习题1.5
如下过程声称可以用来检测LISP解释器是以何种方式计算复合式的:
; 检测解释器计算方式
; 先定义一个死循环
(define (p) (p))
; 再定义一个短路检测器
(define (test x y)
(if (= x 0)
x
y))
; 最后执行(test 0 (p))即可
; 若解释器死循环,那么说明该解释器是应用式的
; 反之,若结果为0,那么说明该解释器是正则式的
扩展:利用lisp实现*方根的牛顿逼*法
; 用牛顿逼*法求*方根*似值
; 块结构 词法作用域
(define (my_sqrt x)
; 求某数的*方
(define (square a) (* a a))
; 求两数的*均数
(define (avg a b)
(/ (+ a b) 2))
; 演化
(define (improved_guess guess)
(avg guess (/ x guess)))
; 定义精度
(define (good_enough? guess)
(< (abs (- (square guess) x)) 0.001))
; 定义循环不变量
(define (sqrt_iter guess)
(if(good_enough? guess)
guess
(sqrt_iter (improved_guess guess))))
(sqrt_iter 1)
)
练习1.6 利用cond实现的if
; 自定义的if
(define (new_if predicate then_clause else_clause)
(cond (predicate then_clause)
(else else_clause)))
然后用自定义的new_if代替求*方根程序中的if
; 前略
(define (sqrt_iter guess)
(if(good_enough? guess)
guess
(sqrt_iter (improved_guess guess))))
在不同版本的LISP实现中,结果都有所不同。
在R5RS中,程序无法正常结束,死循环。
练习1.8 立方根的牛顿逼*
; 计算立方根
(define (cube_root x)
; 计算一个数的*方
(define (square a)
(* a a ))
; 计算一个数的立方
(define (cube a)
(* a a a))
; 定义计算精度
(define (good_enough? guess)
(<(abs (- (cube guess) x)) 0.001))
; 演变
(define (improved_guess y)
(/ (+ (/ x (square y)) (* 2 y))
3))
; 循环不变量
(define (cube_root_iter guess)
(if(good_enough? guess)
guess
(cube_root_iter(improved_guess guess))))
; 主函数体
(cube_root_iter 1))
练习1.9
利用代换模型分别描述一下两种过程,并判断过程属于递归或是迭代
; 两正数相加,方式一
(define (+ a b)
(if(= a 0)
b
(inc (+ (dec a) b))
))
; 两正数相加,方式二
(define (+ a b)
(if (= a 0)
b
(+ (dec a) (inc b))))
练习1.11
递归式
(define (f n)
(cond ((< n 3) n)
(else
(+
(f (- n 1))
(* (f (- n 2)) 2)
(* (f (- n 3)) 3)))))
迭代式
(define (f n)
(cond ((< n 3) n)
(else (ff 0 1 2 3 n))))
(define (ff a b c x n)
(if (= x n)
(calc a b c)
(ff b c (calc a b c) (+ x 1) n)))
(define (calc a b c)
(+ c (* 2 b) (* 3 a)))
注:迭代式实在快太多了,f(100)秒出结果,递归式算了半天没反应。
练习1.12
递归计算帕斯卡三角
(define (pascal row col)
(cond ((= col 1) 1)
((= row col) 1)
(else
(+
(pascal (- row 1) (- col 1))
(pascal (- row 1) col)
))))