SICP 课后题及相关笔记 1

练习 1.3

Exercise 1.3. Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.

这题定义的过程要求求出三个数中两个最大数字的平方和,如果先求出两个最大数,然后分别求平方再求和在实现上比较麻烦,可先求出三个数平方和之 后减去最小数的平方,则只需要实现过程 smaller 求出最小数字即可。

最终在 DrRacket 环境下的实现:

(define sum-of-squares (lambda (x y z) (+ (* x x) (* y y) (* z z))))

(define (smaller x y z)
  (cond ((and (< x y) (< x z)) x)
        ((and (< y x) (< y z)) y)
        (else z)))

(define (bigger-sum-of-squares x y z)
  (- (sum-of-squares x y z) (* (smaller x y z) (smaller x y z))))

练习 1.5

Exercise 1.5. Ben Bitdiddle has invented a test to determine whether the interpreter he is faced with is using applicative-order evaluation or normal-order evaluation. He defines the following two procedures:

(define (p) (p))

(define (test x y)
(if (= x 0)
0
y))

Then he evaluates the expression

(test 0 (p))

What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What behavior will he observe with an interpreter that uses normal-order evaluation? Explain your answer. (Assume that the evaluation rule for the special form if is the same whether the interpreter is using normal or applicative order: The predicate expression is evaluated first, and the result determines whether to evaluate the consequent or the alternative expression.)

如果是 normal-order evaluation 的话,在调用 test 这个 proceudre 的时候会先对两个参数求值,第二个参数 (p) 求值会使解释器进入死循环,不停调用自身。但如果是 applicative-order 的话,解释器并不会对 (p) 求值,而是直接返回 0。

练习 1.6

Exercise 1.6. Alyssa P. Hacker doesn’t see why if needs to be provided as a special form. “Why can’t I just define it as an ordinary procedure in terms of cond?” she asks. Alyssa’s friend Eva Lu Ator claims this can indeed be done, and she defines a new version of if:

(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))

Eva demonstrates the program for Alyssa:

(new-if (= 2 3) 0 5)
5

(new-if (= 1 1) 0 5)
0

Delighted, Alyssa uses new-if to rewrite the square-root program:

(define (sqrt-iter guess x)
(new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))

What happens when Alyssa attempts to use this to compute square roots? Explain.

首先尝试用题目中所给的 new-if 过程来写 sqrt 并尝试运行

(define (sqrt-iter guess x)
  (new-if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))

(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))

(define (improve guess x)
  (average guess (/ x guess)))

(define (average x y)
  (/ (+ x y) 2))

(define (square guess) (* guess guess))

(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))

(define (sqrt x)
  (sqrt-iter 1.0 x))

然后尝试调用 (sqrt 9) ,发现程序死循环了。原因是 scheme 中的 if 的求值方法是,先求值 predicate,如果为 True 则求值 then-clause,否则求值 else-clause,但是由于解释器的实现是 applicative-order,所以 new-if 中的求值方法是直接对 predicate then-clause else-clause 求值,这就导致程序进入了死循环。

练习 1.11

Exercise 1.11. A function f is defined by the rule that f(n) = n if n<3 and f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) if n> 3. Write a procedure that computes f by means of a recursive process. Write a procedure that computes f by means of an iterative process.

递归的写法很简单,采用迭代计算过程,首先考虑递归展开树,发现和斐波拉契数列展开树很相似,可以把 f(n - 1)、f(n - 2)、f(n - 3) 三个数字存在变量里避免重复计算结点,最终得到的迭代计算过程:

(define (f n)
  (if (< n 3)
      n
      (f-iter 0 1 2 0 (- n 3))))

(define (f-iter last3 last2 last1 i n)
  (if (= i n)
      (+ last1 (* 2 last2) (* 3 last3))
      (f-iter last2
              last1
              (+ last1 (* 2 last2) (* 3 last3))
              (+ i 1)
              n)))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值