SICP习题解答:第一章(下)

?View Code SCHEME
;; 1.29
(define (simpson-integral f a b n)
  (define (coefficient i)
    (cond ((or (= i 0) (= i n)) 1)
          ((even? i) 2)
          (else 4)))
  (let ((h (/ (- b a)n )))
    (* (/ h 3)
       (sum (lambda (i) (* (f (+ a (* i h))) (coefficient i)))
            0
            (lambda (i) (+ i 1))
            n))))
 
;; 1.30
(define (sum term a next b)
  (define (iter a result)
    (if (> a b)
        result
        (iter (next a) (+ result (term a)))))
  (iter a 0))
 
;; 1.31 只需要把sum改动两处。
; 递归实现
(define (product term a next b)
  (if (> a b)
      1
      (* (term a)
         (product term (next a) next b))))
 
; 迭代实现
(define (product term a next b)
  (define (iter a result)
    (if (> a b)
        result
        (iter (next a) (* result (term a)))))
  (iter a 1))
 
; 阶乘
(define (factorial n)
  (product (lambda (x) x) 1 (lambda (i) (+ 1 i)) n))
 
; π的近似值
(define (calc-pi n)
  (define (term i)
    (/ (- (square i) 1) (square i)))
  (define (next i)
    (+ 2 i))
  (* 4 (product term 3.0 next n)))
 
;; 1.32
(define (accumulate combiner null-value term a next b)
  (if (> a b)
      null-value
      (combiner (term a)
                (accumulate combiner null-value term (next a) next b))))
 
(define (accumulate combiner null-value term a next b)
  (define (iter a result)
    (if (> a b)
        result
        (iter (next a) (combiner result (term a)))))
  (iter a null-value))
 
;; 1.33
; filtered-accumulate 的两种实现
(define (filtered-accumulate combiner null-value term a next b filter)
  (define (do-filter x)
    (if (filter x) x null-value))
  (if (> a b)
      null-value
      (combiner (do-filter (term a))
                (filtered-accumulate combiner null-value term (next a) next b filter))))
 
(define (filtered-accumulate combiner null-value term a next b filter)
  (define (do-filter x)
    (if (filter x) x null-value))
  (define (iter a result)
    (if (> a b)
        result
        (iter (next a) (combiner result (do-filter (term a))))))
  (iter a null-value))
 
; (a)
(filtered-accumulate + 0 (lambda (x) x) a (lambda (i) (+ 1 i)) b prime?)
; (b)
(filtered-accumulate * 1 (lambda (x) x) 1 (lambda (i) (+ 1 i)) (- 1 n) (lambda (a) (= 1 (gcd a n))))
 
;; 1.34 (f f)相当于(f 2),相当于(2 2),会因为2并非可以调用的函数而出错。
 
;; 1.35 证明不动点直接计算即可,计算的(fixed-point (lambda (x) (+ 1 (/ 1 x))) 1.0)。
 
;; 1.36 全部代码如下
(define tolerance 0.00001)
 
(define (fixed-point f first-guess)
  (define (close-enough? v1 v2)
    (< (abs (- v1 v2)) tolerance))
  (define (try guess)
    (display guess)
    (newline)
    (let ((next (f guess)))
      (if (close-enough? guess next)
          next
          (try next))))
  (try first-guess))
 
(define (f x) (/ (log 1000) (log x)))
 
(display (fixed-point f 2))
(newline) (newline)
(display (fixed-point (lambda (x) (average x (f x))) 2))
(newline) (newline)
 
; 使用与不使用平均阻尼的步数分别为9与34步。
 
;; 1.37
; 递归版本
(define (cont-frac n d k)
  (define (shift f)
    (lambda (i) (f (+ 1 i))))
  (if (= 0 k)
      0
      (/ (n 1) (+ (d 1) (cont-frac (shift n) (shift d) (- k 1))))))
 
; 迭代版本
(dsefine (cont-frac n d k)
  (define (iter result i)
    (if (= 0 i)
        result
        (iter (/ (n i) (+ (d i) result)) (- i 1))))
  (iter 0 k))
 
; 当k不小于11时,结果有4位精度。
 
;; 1.38
(define (e-2 k)
  (cont-frac (lambda (i) 1.0)
             (lambda (i)
               (if (= 2 (remainder i 3))
                   (* 2 (/ (+ 1 i) 3))
                   1))
             k))
 
;; 1.39
(define (tan-cf x k)
  (cont-frac (lambda (i)
               (if (= 1 i) x (- (square x))))
             (lambda (i)
               (- (* 2 i) 1))
             k))
 
;; 1.40
(define (cubic a b c)
  (lambda (x)
    (+ c (* x (+ b (* x (+ a x)))))))
 
;; 1.41
; double函数
(define (double f)
  (lambda (x)
    (f (f x))))
 
;; (((double (double double)) inc) 5) 的值为21。因为 (double double) 得到一个把参数过程应用四次的函数,而 (double (double double)) 事实上是将“把参数过程应用四次”的过程应用两次,也就是一个将参数过程应用十六次的函数。
 
;; 1.42
(define (compose f g)
  (lambda (x) (f (g x))))
 
;; 1.43
(define (repeated f n)
  (if (= 1 n)
      f
      (compose f (repeated f (- n 1)))))
 
;; 1.44
(define (n-times-smooth f dx n)
  ((repeated (lambda (f) (smooth f dx)) n) f))
 
;; 1.45
(define (calc-nth-root-with-t-average-damps x n t)
  (fixed-point ((repeated average-damp t) (lambda (y) (/ x (fast-expt y (- n 1))))) 1.0))
 
;; 通过实验,得到的规律是,当 2^t>=n 时,用 t 次平均阻尼求 n 次方根是可行的,于是有下面的程序。
(define (nth-root x n)
  (define (minimal-t n)
    (if (= 1 n)
        0
        (+ 1 (minimal-t (quotient n 2)))))
  (calc-nth-root-with-t-average-damps x n (minimal-t n)))
 
;; 1.46
(define (iterative-improve guess improve good-enough?)
  (if (good-enough? guess)
      guess
      (iterative-improve (improve guess) improve good-enough?)))
 
(define (sqrt x)
  (define (improve y)
    (/ (+ x (square y)) (* 2 y)))
  (define (good-enough? y)
    (> tolerance (abs (- (square y) x))))
  (iterative-improve 1.0 improve good-enough?))
 
(define (fixed-point f first-guess)
  (define (improve x)
    (f x))
  (define (good-enough? x)
    (> tolerance (abs (- (f x) x))))
  (iterative-improve first-guess improve good-enough?))

2 Comments »

  1. bobye Said,

    November 29, 2008 @ 18:59

    SICP 的解答貌似浙大这个老师有给出过,我一个同学(也是浙大的)就从他那获得了SICP的教学视频和解答。

    另外我本人看到完了两三章,做了一点笔记,可惜现在没有更多时间把它看完了。

  2. oh,BB.hacking Said,

    April 23, 2009 @ 15:34

    我的BLOG ….有这本书的视频?? 哇撒 能发给我吗? 用邮件bb.qnyd@gmail.com

Leave a Comment