Fork me on GitHub

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)
          ))))
posted @ 2016-07-13 21:51  alchimistin  阅读(248)  评论(0编辑  收藏  举报