1. Building Abstractions with Procedures

62 阅读2分钟

1.2

#lang sicp
(/ (+ 5 4 (- 2 
             (- 3 
                (+ 6 
                   (/ 4 5)))))
   (* 3 (- 6 2) (- 2 7)))

1.3

#lang sicp
(define (sum_of_square a b)
     (+ (* a a) (* b b))
)
(define (p a b c) 
    (cond
        ((> a b) (if (> c b)
                    (sum_of_square a c)
                    (sum_of_square a b)))
        ((= a b) (if (> c a)
                    (sum_of_square c a)
                    (sum_of_square a b)))
        (else (if (> c a)
                   (sum_of_square b c)
                   (sum_of_square b a)))
))

(p 1 2 3)
(p 1 3 2)
(p 2 1 3)
(p 2 3 1)
(p 3 1 2)
(p 3 2 1)

输出

13
13
13
13
13
13

1.9

第一个是递归的 第二个是迭代的

重点:尾递归。不同于c或者其他语言,scheme实际是用迭代来实现尾递归的,也就是虽然尾递归写法上符合递归函数,但实际为迭代实现

It will execute an iterative process in constant space, even if the iterative process is described by a recursive procedure.

1.11

#lang sicp
(define (f_recursive n) (
    if (< n 3) n
    (+ (f_recursive (- n 1))
       (* 2 (f_recursive (- n 2)))
       (* 3 (f_recursive (- n 3))))
))


(f_recursive 5)

(define (f_iter n)
    (define (f_i n a b c i)
        (cond ((< n 3) n)
              ((= i n) a)
              (else (f_i n (+ a (* 2 b) (* 3 c)) a b (+ i 1)))))
    (f_i n 2 1 0 2)
)

(f_iter 5)

1.12

#lang sicp
(define (triangle row column) (
    if (or (= column 1) (= column row)) 1
    (+ (triangle (- row 1) (- column 1))
       (triangle (- row 1) column))
))

(triangle 1 1)
(triangle 2 1)
(triangle 2 2)
(triangle 5 2)
(triangle 5 3)
(triangle 5 4)

1.16

迭代实现快速幂

#lang sicp

(define (even? n)
(= (remainder n 2) 0))

(define (square n)
(* n n))

(define (fast_expt b n)
    (define (fast_expt_iter a b n)(
        cond ((= n 0) a)
             ((even? n) (fast_expt_iter a (square b) (/ n 2)))
             (else (fast_expt_iter (* a b) b (- n 1)))
    ))
    (fast_expt_iter 1 b n)
)

(fast_expt 3 10)

1.28

题目描述有问题

It is also possible to prove that if n is an odd number that is not prime, then, for at least half the numbers a < n, computing a^{n - 1} in this way will reveal a nontrivial square root of 1 modulo n.

比如n = 9就有问题了(害我花了很久,还以为自己理解错了,坑爹啊)

正确描述参考:stackoverflow.com/questions/5…

1.29

#lang sicp

(define (even? n)
(= (remainder n 2) 0))

(define (square n)
(* n n))

(define (cube n)
(* n n n))

(define (inc n)
  (+ n 1))

(define (sum term a next b)
  (if (> a b)
      0
      (+ (term a)
         (sum term (next a) next b))))

(define (simpson f a b n)
  (define  h (/ (- b a) n))
  (define (simpson_term n)
    (* (f (+ a (* n h)))
       (if (even? n) 2 4)))
  (* (/ h 3)
     (+ (f a)
        (sum simpson_term 1 inc (- n 1))
        (f (+ a (* n h)))))
  )

(simpson cube 0 1 100)

1.31

(define (identity x) x)

(define (prod term a next b)
  (if (> a b)
      1
      (* (term a)
         (prod term (next a) next b))))

(define (fac n)
  (prod identity 1 inc n))

(fac 4)

1.37

递归

(define (cont_frac nf df k)
  (define (cont_frac_recur i)
    (if (= i k)
      (/ (nf i) (df 1))
      (/ (nf i)
         (+ (df i) (cont_frac_recur (+ i 1))))))
  (cont_frac_recur 1))

(/ 1 (cont_frac (lambda (i) 1.0)
                (lambda (i) 1.0)
                10))

迭代

(define (cont_frac_iter nf df k)
  (define (cfi result i)
    (if (= i 0)
      result
      (cfi (/ (nf i) (+ (df i) result)) (- i 1))))
  (cfi 0 k))

(/ 1 (cont_frac_iter (lambda (i) 1.0)
                     (lambda (i) 1.0)
                     10))