Exercise 1.30/1.31/1.32/1.33

1.30

 
Exercise 1.30. The sum procedure above generates a linear recursion. The procedure can be rewritten so
that the sum is performed iteratively. Show how to do this by filling in the missing expressions in the
following definition:

 1.30的题目就是把一个递归方法sum改写成迭代。原来的sum方法是:

(defun sum (term a next b)
  (if (> a b)
      0
    (+ (funcall term a)
       (sum term (funcall next a) next b))))

 变成下面这种样子:

(defun sum (term a next b)
  (defun iter (a result)
    (if <??>
        <??>
      (iter <??> <??>)))
  (iter <??> <??>))

 当然了,你需要补齐那些问号。实现起来很简单,只需要使用result记录第n次迭代时,前面n-1次的和就可以了。

 

(defun sum-iter (term a next b)
  (defun iter (a result)
    (if (> a b)
        result
    (iter (funcall next a) (+ result (funcall term a)))))
  (iter a 0))

 

1.31

1.30里面实现了累加,这里需要实现连乘了。同时给出递归和非递归版本。参考前面sum的实现,别忘了把加号改成乘号,然后把默认值从0变成1:

(defun product (term a next b)
  (if (> a b)
      1
    (* (funcall term a)
       (product term (funcall next a) next b))))
 
(defun product-iter (term a next b)
  (defun iter (a result)
    (if (> a b)
        result
      (iter (funcall next a ) (* result (funcall term a)))))
  (iter a 1))
(product-iter #'(lambda (x) x) 1 #'(lambda (x) (+ x 1)) 3)

 对于pi的运算,采用下面的公式:



 使用上面的共识,我们让a=1,b等于迭代的次数,下面需要确认的就是term方法了。

我们把上面一个公式,两个两个拆开,就变成了这样:

写道
2 × 4 / (3 * 3)
4 × 6 / (5 * 5)
6 × 8 / (7 * 7)
....

 对于第n行,分母是 (2n+1)的平方, 分子是 2n × 2(n+1), 所以term应该是:

(defun pi-term (x)
  (/ (* (* 2 x) (* 2 (+ 1 x)))
     (* (+ 1 (* 2 x))
        (+ 1 (* 2 x))
        )))

(* 4 (product #'pi-term 1 #'(lambda (x) (+ x 1)) 3))
(* 4 (product-iter #'pi-term 1 #'(lambda (x) (+ x 1)) 3))

 

 

 1.32

把前面的sum、product再做一层抽象,编写一个accumulate函数,它与sum、product相比,多了两个参数:

combiner 对元素使用什么样的操作

null-value 元素使用完毕的值,所以,实现这样一个方法:(accumulate combiner null-value term a next b)

 

(defun accumulate (combiner null-value term a next b)
  (if (> a b)
      null-value
    (funcall combiner
             (funcall term a)
             (accumulate combiner null-value term (funcall next a) next b)))
  )
(defun accumulate-iter (combiner null-value term a next b)
  (defun iter (a result)
    (if (> a b)
        (print result)
      (iter (funcall next a)
            (funcall combiner
                     a
                     result))))
  (iter a null-value))

 

下面轻松定义sum和product

(defun acc-sum (term a next b)
  (accumulate #'+ 0 term a next b))

(defun acc-sum-iter (term a next b)
  (accumulate-iter #'+ 0 term a next b))

(defun acc-product (term a next b)
  (accumulate #'* 1 term a next b))

(defun acc-product-iter (term a next b)
  (accumulate-iter #'* 1 term a next b))

 来测试一下:

(defun next (x) (+ x 1))
(acc-sum #'(lambda (x) x) 1 #'next 10)
(acc-sum-iter #'(lambda (x) x) 1 #'next 10)
(acc-product #'(lambda (x) x) 1 #'next 4)
(acc-product-iter #'(lambda (x) x) 1 #'next 4)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值