sicp 流 函数(3-53 to 3-58,3-59,3-60,3-61,3-62 答案)


;;; -------- 3.53 ------------------------------
(define (add-stream s1 s2)
  (stream-map + s1 s2))

define s (cons-stream 1 (add-stream s s)))
定义 2^n 流函数(n为从0开始的整数, 为流的第n个元素)



;;; --------- 3.54 -----------------------------
(define (mul-streams s1 s2)
  (stream-map * s1 s2))
(define (add-streams s1 s2)
  (stream-map + s1 s2))
(define ones (cons-stream 1 ones))
(define integers (cons-stream 1 (add-streams ones integers)))

(define factorials (cons-stream 1 (mul-streams factorials integers)))



;;; ----------- 3.55 ----------------------------
(define (partial-sums stream)
  (define sumers
    (cons-stream (stream-car stream)
         (add-streams sumers
                  (stream-cdr stream))))
  sumers)



;;; ------------ 3.56 --------------------
(define (scale-stream stream factor)
  (stream-map (lambda (x) (* x factor)) stream))

(define (merge s1 s2)
  (cond ((stream-null? s1) s2)
    ((stream-null? s2) s1)
    (else
     (let ((s1car (stream-car s1))
           (s2car (stream-car s2)))
       (cond ((< s1car s2car)
          (cons-stream s1car (merge (stream-cdr s1) s2)))
         ((> s1car s2car)
          (cons-stream s2car (merge s1 (stream-cdr s2))))
         (else
          (cons-stream s1car (merge (stream-cdr s1)

                        (stream-cdr s2)))))))))


(define S (cons-stream 1 (merge (scale-stream S 2)
                (merge (scale-stream S 3)
                       (scale-stream S 5)))))

;;; --------------- 3.57 -----------------------------
如果简单地用(lambda () exp) 实现 (delay exp)的话, 每次获取流中的第n个元素,都得从头使用fibgen计算到第n个元素为止,
与正常的迭代计算斐波那契数所需的工作量一般大。 所以带记忆版本的流有助于减少计算的工作量,不过需要更多额外的内存空间。

;;; --------------- 3.58 -----------------------------
(define (expand num den radix)
  (cons-stream
   (quotient (* num radix) den)
   (expand (remainder (* num radix) den) den radix)))

; 这段程序求 num/den, 并以radix为基数构成一个无限流。
(expand 1 7 10) ;结果为 1/7 = (1 4 2 8 5 7 1 4 2 8 5 7 ....)
(expand 3 8 10) ;结果为 3/8 = (3 7 5 0 0 0 0 0 0 0 0 0 ....)


;;; --------------- 3.59 -----------------------------

a. 流的每个元素除以整数就可以

(define (integrate-series stream)
  (div-streams stream integers))

b. 上面定义的 (integrate-series stream) 结果可认为是stream流的积分(缺少常数项)。

 ex的倒数等于ex,而ex的常数项为1,所以ex也等于 1加上ex的积分

(define exp-series
  (cons-stream 1 (integrate-series exp-series)))


  由于sin的倒数是cos, 所以sin就是 cos的倒数加上一个常数项, 有 sin的多项式定义可得:

(define sine-series
  (cons-stream 0 (integrate-series cosine-series)))


同理获得cos的定义,cos和sin两个级数递归调用形成无限流
(define cosine-series
  (cons-stream 1 (stream-map (lambda (x) (- x))
                 (integrate-series sine-series))))


;;; --------------- 3.60 -----------------------------

两个级数相乘,等于级数s1的每一项与s2中的每一项相乘(注意:不是一对一的相乘)

方法是: s1和s2相乘所得结果的第一项肯定是s1的第一项乘以s2的第一项,

至于第二项后的结果为:s1的第一项与s2的第二项以及之后的项相乘之和, 再加上s1除去第一项与s2的所有项相乘所得结果。

(define (mul-series s1 s2)
  (cons-stream (*
        (stream-car s1)
        (stream-car s2))
           (stream-map + (scale-stream
                  (stream-cdr s2)
                  (stream-car s1))
               (mul-series
                (stream-cdr s1)
                s2))))
          
使用sin2x + cos2x = 1验证:

define one (add-streams (mul-series sine-series sine-series)
         (mul-series cosine-series cosine-series)))

(stream-ref one 0)  ==>  1

(stream-ref one N)  ==> 0    ; N表示除了0以外的其他数


;;; --------------- 3.61 -----------------------

;;; 定义常数项为1的级数的倒数
(define (invert-unit-series s)
  (define invert-dummy
    (cons-stream 1 (scale-stream
         (mul-series (stream-cdr s) invert-dummy)
         -1)))
  invert-dummy)


;;; -------------- 3..62 ---------------------

;;; 先定义第一项非零的级数的倒数
(define (invert-series s)
  (let ((constant-term (stream-car s)))
    (if (= constant-term 0)
    (error "DIV-SERIES denom constant term can't be zero")
    (scale-stream (invert-unit-series
               (scale-stream s (/ 1 constant-term)))
              constant-term))))

;;; 两个级数相除等级分子的级数乘以分母的级数
(define (div-series num denom)
    (mul-series num
            (invert-series denom)))

;;; 定义tan的级数, tan = sin / cos
(define tan-series (div-series sine-series cosine-series))

;;; 下面显示 tan级数前10项的值
(stream-ref tan-series 0)

1 ]=>
;Value: 0

(stream-ref tan-series 1)
1 ]=>
;Value: 1

(stream-ref tan-series 2)
1 ]=>
;Value: 0

(stream-ref tan-series 3)
1 ]=>
;Value: 1/3

(stream-ref tan-series 4)
1 ]=>
;Value: 0
(stream-ref tan-series 5)
1 ]=>
;Value: 2/15
(stream-ref tan-series 6)
1 ]=>
;Value: 0
(stream-ref tan-series 7)
1 ]=>
;Value: 17/315
(stream-ref tan-series 8)
1 ]=>
;Value: 0
(stream-ref tan-series 9)
1 ]=>
;Value: 62/2835
1 ]=>



参考: http://wizardbook.wordpress.com/solutions-index/      ------- SICP参考答案


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值