SICP 笔记

  • 过程应用
  • 代换模型
  1. 求值该组合式的各子表达式
  2. 将作为最左子表达式(运算符)的值的那个过程应用于相应的实际参数,所谓实际参数也就是其他子表达式(运算对象)的值

应用序求值(解释器实际使用)

解释器首先对运算符和各个运算对象求值,而后将得到的过程应用于得到的实际参数。 正则序求值

求值模型

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

应用序 会先计算(p) 这样 (p)调用(p)一直无限循环下去
如果是正则序

(define (square x)
    (* x x))

牛顿法求平方根 -- 逐步逼近方法

(define (square x)
    (* x x))
(define (sqrt-iter guess x)
    (if (good-enough? guess x)
        guess
        (sqrt-iter (improve guess x)
          x)))
(define (improve guess x)
    (everage guess (/ x guess)))
(define (everage x y)
    (/ (+ x y) 2))
(define (good-enough? guess x)
    (< (abs (- (square guess) x)) 0.001))
(define (my-sqrt x)
    (sqrt-iter 1.0 x))
;;~~~~~~~~~~~~~~~~
(define (new-if predicate then-clause else-clause)
    (cond
      [predicate then-clause]
      [else else-clause]))
(define (sqrt-iter guess x)
    (new-if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x) x)))

局部化

内部定义和快结构

(define (my-sqrt x)
    (define (good-enough? prev guess)
      (if (< (abs (- guess prev)) 0.00000000001)
          #t
          #f))
    (define (sqrt-iter prev guess x)
      (if (good-enough? prev guess)
          guess
          (sqrt-iter guess (improve guess x) x)))
    (define (improve guess x)
      (everage guess (/ x guess)))
    (define (everage x y)
      (/ (+ x y) 2))
    (sqrt-iter 0 1.0 x))

这种嵌套的定义称为块结构

简化:词法作用域

(define (my-sqrt x)
    (define (good-enough? prev guess)
      (if (< (abs (- guess prev)) 0.00000000001)
          #t
          #f))
    (define (sqrt-iter prev guess)
      (if (good-enough? prev guess)
          guess
          (sqrt-iter guess (improve guess))))
    (define (improve guess)
      (everage guess (/ x guess)))
    (define (everage x y)
      (/ (+ x y) 2))
    (sqrt-iter 0 1.0))

线性的递归 VS 迭代

(define (factorial n)
    (if (= n 1)
        1
        (* n (factorial (- n 1)))))

迭代

1.计数器
2.维持一个变动的乘积

    (define (fact-iter product counter max-count)
        (if (> counter max-count)
            product
            (fact-iter (* counter product)
              (1+ counter)
              max-count)))
    (define (factorial n)
        (fact-iter 1 1 n))
    (factorial 6)

tree-sum

(define tree-sum
    (lambda (exp)
      (match exp
        [(? number? x) x]
        [`(,e1 ,e2)
         (let ([v1 (tree-sum e1)]
               [v2 (tree-sum e2)])
           (+ v1 v2))])))

fib => n = (n - 1) + (n - 2)

(define (fib n)
    (cond
      [(= n 0) 0]
      [(= n 1) 1]
      [else (+ (fib (- n 1))
               (fib (- n 2)))]))

(define (fib n)
    (fib-iter 1 0 n))
(define (fib-iter a b count)
    (if (= count 0)
        b
        (fib-iter (+ a b) a (- count 1))))

count change

(define (count-change amount)
    (cc amount 5))
(define (cc amount kinds-of-coins)
    (cond ((= amount 0) 1)
          ((or (< amount 0) (= kinds-of-coins 0)) 0)
          (else (+ (cc amount
                     (- kinds-of-coins 1))
                  (cc (- amount
                        (first-denomination kinds-of-coins))
                    kinds-of-coins)))))
(define (first-denomination kinds-of-coins)
    (cond
      ((= kinds-of-coins 1) 1)
      ((= kinds-of-coins 2) 5)
      ((= kinds-of-coins 3) 10)
      ((= kinds-of-coins 4) 25)
      ((= kinds-of-coins 5) 50)))
(count-change 100)

(define (my-expt b n)
    (if (= n 0)
        1
        (* b (my-expt b (- n 1)))))

(define (expt2 b n)
    (define (expt-iter b counter product)
              (if (= counter 0)
                  product
                  (expt-iter b (1- counter) (* b product))))
    (expt-iter b n 1))

Section 8.4 Examples

(define-syntax rec
    (syntax-rules ()
      [(_ x e) (letrec ([x e]) x)]))
(map (rec sum (lambda (x)
                  (if (= x 0)
                      0
                      (+ x (sum (- x 1))))))
    '(0 1 2 3 4 5))

(define-syntax rec
    (syntax-rules ()
      [(_ x e) (letrec ([x e]) x)]))
(define-syntax let
    (syntax-rules ()
      [(_ ((x e) ...) b1 b2 ...)
       ((lambda (x ...) b1 b2 ...) e ...)]
      [(_ f ((x e) ...) b1 b2 ...)
       ((rec f (lambda (x ...) b1 b2 ...)) e ...)]))

e.g.

(let f ([ls '(1 2 3 4)] [sum 0])
    (if (null? ls)
        sum
        (f (cdr ls) (+ sum (car ls)))))

version 2.

(define-syntax let
    (syntax-rules ()
      [(_ ((x e) ...) b1 b2 ...)
       ((lambda (x ...) b1 b2 ...) e ...)]
      [(_ f ((x e) ...) b1 b2 ...)
       ((letrec ([f (lambda (x ...) b1 b2 ...)]) f) e ...)]))

log-fib

(define (fib n)
    (define (fib-iter a b p q count)
      (cond
        [(= count 0) b]
        [(even? count)
         (fib-iter a
           b
           p  
           (+ q 1)
           (/ count 2))]
        [else (fib-iter (+ (* b q) (* a q) (* a p))
                (+ (* b p) (* a q))
                p
                q
                (- count 1))]))
    (fib-iter 1 0 0 1 n))

GCD [modified version]

(define (gcd  a b)
    (if (< a b)
        (if (= a 0)
            b
            (gcd a (remainder b a)))
        (if (= b 0)
            a
            (gcd b (remainder a b)))))
;; book
(define (gcd a b)
    (if (= b 0)
        a
        (gcd b (remainder a b))))

prime

(define (smallest-divisor n)
    (find-divisor n 2))
(define (square n)
    (* n n))
(define (find-divisor n test-divisor)
    (cond
      [(> (square test-divisor) n) n]
      [(divides? test-divisor n) test-divisor]
      [else (find-divisor n (+ test-divisor 1))]))
(define (divides? a b)
    (= (remainder b a) 0))
(define (prime? n)
    (= n (smallest-divisor n)))

fast-prime

(define (square n)
    (* n n))
(define (expmod base exp m)
    (cond
      [(= exp 0) 1]
      [(even? exp)
       (remainder
         (square (expmod base (/ exp 2) m)) m)]
      [else
        (remainder
          (* base (expmod base (- exp 1) m)) m)]))
(define (fermat-test n)
    (define (try-it a)
      (= (expmod a n n) a))
    (try-it (+ 1 (random (- n 1)))))
(define (fast-prime? n times)
    (cond
      [(= times 0) #t]
      [(fermat-test n) (fast-prime? n (- times 1))]
      [else #f]))

(define (timed-prime-test n)
    (newline)
    (display n)
    (start-prime-test n (runtime)))
(define (start-prime-test n start-time)
    (if (prime? n)
        (report-prime (- (runtime) start-time))))
(define (report-prime elapsed-time)
    (display " *** ")
    (display elapsed-time))

ChezScheme Version

(define (timed-prime-test n)
    (newline)
    (display n)
    (start-prime-test n (current-time)))
(define (start-prime-test n start-time)
    (if (prime? n)
        (report-prime (time-difference (current-time) start-time))))
(define (report-prime elapsed-time)
    (display " *** ")
    (display elapsed-time))

if n is not prime it must have a divisor less than or equal to (sqrt n).

Fermat's Little Theorem

If n is a prime number and a is any positive integer less than n, then a raised to the nth power is congruent to a modulo n.
In fact, Carmichael numbers are also called Fermat pseudoprimes

Leave a Comment

Your email address will not be published. Required fields are marked *

PHP 8.1.1 - 14.227 ms, 0 Q