• sicp第二章部分习题解答


    (begin
        (load "ex1.scm")
        ;(define (make-rat n d) (cons n d))
        (define (numer x) (car x))
        (define (denom x) (cdr x))
    
        (define (print-rat x)
          (display (numer x))
          (display "/")
          (display (denom x))
          (newline))
        ;ex 2.1    
        (define (positive? x) (> x 0))    
        (define (negative? x) (< x 0))
        (define (make-rat n d)
            (let ((g (gcd n d)))
            (if (positive? (* n d))
                (cons (/ (abs n) g) (/ (abs d) g))
                (cons (/ (- (abs n)) g) (/ (abs d) g)))))
        ;ex 2.2
        (define (make-point x y)
            (cons x y))
        (define (x-point p)(car p))
        (define (y-point p)(cdr p))
        
        (define (print-point p)
            (display "x:")
            (display (x-point p))
            (display " y:")
            (display (y-point p))
            (newline)
        )
        (define (make-segment p1 p2) (cons p1 p2))
        (define (start-segment s)(car s))
        (define (end-segment s)(cdr s))
        (define (print-segment s)
            (display "[start:")
            (display (x-point (start-segment s)))
            (display " ")
            (display (y-point (start-segment s)))
            (display "] ")
            (display "[end:")
            (display (x-point (end-segment s)))
            (display " ")
            (display (y-point (end-segment s)))
            (display "]")
            (newline)        
        )
        ;线段长度
        (define (length-segment s)
            (sqrt (+ (square (- (x-point (start-segment s)) (x-point (end-segment s))))
                 (square (- (y-point (start-segment s)) (y-point (end-segment s)))))))
        ;线段中点         
        (define (midpoint-segment s)
            (make-point (average (x-point (start-segment s)) (x-point (end-segment s))) 
            (average (y-point (start-segment s)) (y-point (end-segment s)))))
        ;ex 2.3
        ;使用2端点定义矩形
        (define (make-rectangle t-left b-right)
            (if (= (y-point t-left) (y-point b-right))
                (error "can't make a rectangle");如果两点构成的线段平行与x轴则无法构成矩形
                (cons t-left b-right)))
        (define (top-left r) (car r))
        (define (bottom-right r) (cdr r))
        ;计算矩形的周长        
        (define (perimeter-rectangle r)
            (* 2
            (+ (abs (- (y-point (top-left r)) (y-point (bottom-right r))))
               (abs (- (x-point (top-left r)) (x-point (bottom-right r)))))))
        ;计算矩形面积
        (define (area-rectangle r)
            (* (abs (- (y-point (top-left r)) (y-point (bottom-right r))))
               (abs (- (x-point (top-left r)) (x-point (bottom-right r))))))
        ;ex 2.4
        (define (cons1 x y)
            (lambda (m) (m x y)))
        (define (car1 z)
            (z (lambda (p q) p)))
        (define (cdr1 z)
            (z (lambda (p q) q)))
        ;ex 2.5 看下 2^2 * 3^3的二进制表示,注:序对不能有负数
        (define (cons2 x y) (* (fast-expt 2 x) (fast-expt 3 y)))
        (define (car2 z)
            (define (iter n z)
                (if (= (remainder z 2) 0)
                    (iter (+ n 1) (/ z 2))
                     n))
            (iter 0 z))
        (define (cdr2 z)
            (define (iter n z)
                (if (= (remainder z 3) 0)
                    (iter (+ n 1) (/ z 3))
                     n))
            (iter 0 z))
        ;ex 2.17    
        (define (last-pair p)
            (define (last-pair-imp front back)
                (if (null? back)
                    (list front)
                    (last-pair-imp (car back) (cdr back))))
            (if (null? p)
                p
                (last-pair-imp (car p) (cdr p))))
        ;ex 2.18
        ;递归
        (define (reverse p)
            (define (reverse-pair-imp front back)
                (cond ((null? back) (list front))
                      (else (append (reverse-pair-imp (car back) (cdr back)) (list front)))))
            (if (null? p)
                p
                (reverse-pair-imp (car p) (cdr p))))
        ;迭代
        (define (reverse2 items)
          (define (iter things answer)
            (if (null? things)
                answer
                (iter (cdr things) 
                      (cons (car things)
                            answer))))
          (iter items nil))            
        ;ex 2.19
        (define us-coins (list 50 25 10 5 1))
        (define uk-coins (list 100 50 20 10 5 2 1 0.5))
        ;: (cc 100 us-coins)
        (define no-more? null?)
        (define except-first-denomination cdr)
        (define first-denomination car)
        (define (cc amount coin-values)
          (cond ((= amount 0) 1)
                ((or (< amount 0) (no-more? coin-values)) 0)
                (else
                 (+ (cc amount
                        (except-first-denomination coin-values))
                    (cc (- amount
                           (first-denomination coin-values))
                        coin-values)))))            
        ;ex 2.20
        (define (same-parity x . y)
            (define (same-parity-imp checker front back)
                (define (process front) (if (checker front)(list front)nil))    
                (if (null? back)(process front)
                    (append (process front) (same-parity-imp checker (car back) (cdr back)))))
            (if (even? x) (same-parity-imp even? x y)
                (same-parity-imp odd? x y)))
        ;ex 2.21
        (define (square-list1 items)
            (map square items))
        ;ex 2.22
        (define (square-list2 items)
          (define (iter things answer)
            (if (null? things)
                answer
                (iter (cdr things) 
                      (cons (square (car things))
                            answer))))
          (reverse2 (iter items nil)))
         ;ex 2.23
        (define (for-each proc items)
          (define (iter things)
            (cond ((null? things))
                (else
                    (proc (car things))
                    (iter (cdr things)))))
         (iter items))
        ;ex 2.27
        (define (deep-reverse tree)
            (cond ((null? tree) nil)
                  ((not (pair? tree)) tree)
                  (else (reverse (map deep-reverse tree)))))          
        ;ex 2.28
        (define (fringe tree)
            (cond ((null? tree) nil)
                  ((not (pair? tree))(list tree))
                  (else (append (fringe (car tree)) (fringe (cdr tree))))))
        ;ex 2.30 使用map
        (define (square-tree tree)
                (cond ((null? tree) nil)
                ((not (pair? tree)) (square tree))
                (else (map square-tree tree))))
        ;ex 2.30直接定义        
        (define (square-tree2 tree)
            (cond ((null? tree) nil)
                ((not (pair? tree)) (square tree))
                (else (cons (square-tree2 (car tree))
                            (square-tree2 (cdr tree))))))
        ;ex 2.31
        (define (tree-map func tree)
            (define (tree-map-imp tree)
                    (cond ((null? tree) nil)
                    ((not (pair? tree)) (func tree))
                    (else (map tree-map-imp tree))))
            (tree-map-imp tree))
        (define (square-tree3 tree) (tree-map square tree))
        ;ex 2.32 产生子集合的方式,将集合a分成两部分(front back)
        ;a的子集合 = back的子集合 + 将front插入到back的所有子集合中产生的集合 
        (define (subsets s)
          (if (null? s)
              (list nil)
              (let ((rest (subsets (cdr s))))
                (display "rest:")(display rest)(newline)
                (append rest (map (lambda (rest) (cons (car s) rest)) rest)))))
        ;ex 2.33
        (define (map2 p sequence)
            (accumulate (lambda (x y) (cons (p x) y)) nil sequence))
        (define (append2 seq1 seq2)
            (accumulate cons seq2 seq1))
        (define (length2 sequence)
            (accumulate (lambda (_ counter) (+ 1 counter)) 0 sequence))
        ;ex 2.34
        (define (horner-eval x coefficient-sequence)
          (accumulate (lambda (this-coeff higher-terms) (+ this-coeff (* x higher-terms)))
                    0
                    coefficient-sequence))
        ;: (horner-eval 2 (list 1 3 0 5 0 1))
        ;ex 2.35
        (define (count-leaves2 t)
            (define (cal node count)
                (if (pair? node) (+ (accumulate cal 0 node) count);当前节点的叶子数+其它兄弟的叶子数
                    (+ 1 count))
            )
            (accumulate cal 0 t))
        
        ;map fringe将((1 11) 10 (2 (3 4 5 (7 8))))) 展开成 ((1 11) (10) (2 3 4 5 7 8))
        ;分别计算每个子表的length累加即可    
        (define (count-leaves3 t)    
            (accumulate (lambda (node counter) (+ (length node) counter)) 0 (map fringe t)))
        ;ex 2.36
        (define a_s (list (list 1 2 3) (list 4 5 6) (list 7 8 9) (list 10 11 12)))
        (define (accumulate-n op init seqs)
          (if (null? (car seqs))
              nil
              (cons (accumulate op init (map car seqs))
                    (accumulate-n op init (map cdr seqs)))))
        ;ex 2.37
        (define _mat (list (list 1 2 3) (list 4 5 6) (list 7 8 9)))
        (define (transpose mat) ;矩阵转置
            (accumulate-n cons nil mat))
        ;其余两个略去...
        
        ;ex 2.38
        ;fold-right和fold-left的主要区别
        ;fold-right op会首先被应用到最右边的成员
        ;fold-left  op首先被应用到最左边的成员
        ;要想op对fold-right和fold-left的任何输入序列都输出相同的结果,op必须满足交换率
        (define fold-right accumulate)
        (define (fold-left op initial sequence)
          (define (iter result rest)
            (if (null? rest)
                result
                (iter (op result (car rest))
                      (cdr rest))))
          (iter initial sequence))
        ;ex 2.39
        (define (reverse3 sequence)
            (fold-right (lambda (x y) (append y (list x))) nil sequence))
        (define (reverse4 sequence)
            (fold-left (lambda (x y) (cons y x)) nil sequence))
        ;ex 2.40
        (define (unique-pairs n)
            (define (process i)
                (map (lambda (j) (list i j)) (enumerate-interval 1 (- i 1)))
            )
         (accumulate append nil (map process (enumerate-interval 1 n))))
        (define (prime-sum? pair)
            (prime? (+ (car pair) (cadr pair))))
    
        (define (make-pair-sum pair)
            (list (car pair) (cadr pair) (+ (car pair) (cadr pair))))     
        (define (prime-sum-pairs n)
            (map make-pair-sum (filter prime-sum? (unique-pairs n))))
        ;ex 2.41
        (define (m-pairs2 n m)
            (define (iter l j ret)
                (cond ((< j 1)
                    (list ret))
                    (else
                    (accumulate
                     append
                     nil
                     (map (lambda (x)
                           (cond ((< x j) nil) 
                                 (else (iter (- x 1) (- j 1) (cons x ret)))))
                            (enumerate-interval 1 l))))))
            (iter n m nil))        
        ;(define (unique-pairs n) (m-pairs n 2))
        ;(((1 2)(3 4))(5 6))->((1 2)(3 4)(5 6))
        (define (flat seq)
            (define (iter seq ret)
                (cond ((not (pair? seq)) ret)
                      ((null? (car seq)) (cons nil ret))
                      ((pair? (car seq))
                        ;可以替换这两行看下区别
                        ;(let ((ret2 (iter (car seq) ret)))
                        ;     (iter (cdr seq) ret2)))                      
                         (let ((ret2 (iter (cdr seq) ret)))
                             (iter (car seq) ret2)))
                      (else (cons seq ret)))              
            )
            (iter seq nil)
        )        
        ;给定一个列表,从中提取n个所有集合
        ;例如(a b c d)->((a b c) (a c d) (a b d) (b c d))
        ;这个简单的问题整了我一天多,对函数式语言还是不熟啊
        (define (pick-n seq n)
            ;(d-table (1 2 3) 1)->((1 2 3) (2 3) (3))
            ;(d-table (1 2 3) 2)->((1 2 3) (2 3))
            ;(d-table (1 2 3) 3)->((1 2 3))
            (define (d-table seq n)
                (cond ((= n 0) nil)
                      (else
                        (if (<= (length seq) n) (list seq)
                            (cons seq (d-table (cdr seq) n ))))))    
            (define (process seq)
                (let ((size (length seq)))
                    (cond ((<= n 1) (if (pair? seq) (list (car seq)) seq))
                          ((<= size n) seq)    
                          (else 
                            (map (lambda (x)(cons (car seq) x)) (pick-n (cdr seq) (- n 1))))))                      
            )
            (flat (map process (d-table seq n)))
        )
        ;更简单的实现
        (define (pick2-n seq n)
            (define (d-table seq n)
                (cond ((= n 0) nil)
                      (else
                        (if (<= (length seq) n) (list seq)
                            (cons seq (d-table (cdr seq) n ))))))    
            (define (process seq)
                (let ((size (length seq)))
                    (cond ((<= n 1) (if (pair? seq) (list (car seq)) seq))
                          ((<= size n) (list seq))    
                          (else 
                            (map (lambda (x)
                                    (if (pair? x)(cons (car seq) x)
                                        (cons (car seq) (list x)))) (pick2-n (cdr seq) (- n 1))))))                      
            )
            (flatmap process (d-table seq n))
        )
        (define (pick3-n seq n)
            ;从n个中选m个->从n-1个中选m个的集合+(将头部取出插入到从n-1个中选m-1个的集合)
            (define (process seq)
                (cond ((<= n 0) (list nil))
                      ((<= (length seq) n) seq)
                      (else
                         (cons (pick3-n (cdr seq) n) (map (lambda (x)(cons (car seq) x)) (pick3-n (cdr seq) (- n 1)))))
                      )
            )
            (flat (process seq))
        )
        (define (unique-pairs2 n) (pick-n (enumerate-interval 1 n) 2))
        ;(define (3-pairs n) (pick-n (enumerate-interval 1 n) 3))
        (define (m-pairs n m) (pick-n (enumerate-interval 1 n) m))
        ;flatmap练习
        (define (test1 i)
            (define (process x)
                (map (lambda (y) (list x y))(enumerate-interval 1 x)) 
            )
            (flatmap process (enumerate-interval 1 i))
        )
        (define (test2 i j)
            (define (process x)
                (map (lambda (y) (list x y))(enumerate-interval 1 j)) 
            )
            (flatmap process (enumerate-interval 1 i))
        )
        ;(flatmap (lambda (x) (map square x)) (list (list 1) (list 2)))
        ;2.31引号
        ;'后的对象表示对象应该作为数据而不是该求值的表达试对待
        ;(accumulate (lambda (x y) (cons (list x) y)) nil ''a)
        ;''a 表示一个列表其内容为(quote a)与(list 'quote 'a),'(quote a)等价
        ;(cons 'quote 'a)->(quote . a)
        ;(cons 'quote (list 'a))-> ''a
        ;(accumulate (lambda (x y) (cons (list x) y)) nil (car '('a))
        ;'('a)表示列表中有一个元素为('a) (car '('a)) 等价于 ''a
        ;比较''a 于 '('a)的区别(car (cdr ''a)) = (car (cdr (car '('a)))) = 'a
        
        ;ex 2.56
        
        (define (variable? x) (symbol? x))
    
        (define (same-variable? v1 v2)
          (and (variable? v1) (variable? v2) (eq? v1 v2)))
    
        ;(define (make-sum a1 a2) (list '+ a1 a2))
    
        ;(define (make-product m1 m2) (list '* m1 m2))
    
        (define (sum? x)
          (and (pair? x) (eq? (car x) '+)))
    
        (define (addend s) (cadr s))
    
        (define (augend s) (caddr s))
    
        (define (product? x)
          (and (pair? x) (eq? (car x) '*)))
    
        (define (multiplier p) (cadr p))
    
        (define (multiplicand p) (caddr p))
        (define (make-sum a1 a2)
          (cond ((=number? a1 0) a2)
                ((=number? a2 0) a1)
                ((and (number? a1) (number? a2)) (+ a1 a2))
                (else (list '+ a1 a2))))
    
        (define (=number? exp num)
          (and (number? exp) (= exp num)))
    
        (define (make-product m1 m2)
          (cond ((or (=number? m1 0) (=number? m2 0)) 0)
                ((=number? m1 1) m2)
                ((=number? m2 1) m1)
                ((and (number? m1) (number? m2)) (* m1 m2))
                (else (list '* m1 m2))))
        ;用base^expon表示base的expon次幂
        (define (make-exponentiation base expon)
            (if (number? expon)
                (cond ((= expon 0) 1)
                      ((= expon 1) base)    
                      (else (list '^ base expon)))
                (list '^ base expon))      
        )
        (define make-exp make-exponentiation)
        (define (exponentiation? e)
            (if (pair? e)(eq? (car e) '^)#f))
        (define is-exp? exponentiation?)
        (define (base e)
            (if (not is-exp?) (error "e is not a exponentiation")
                (car (cdr e))))            
        (define (exponent e);获得指数
            (if (not is-exp?) (error "e is not a exponentiation")
                (car (cddr e))))        
        (define (exponent-dec e);指数-1
            (let ((expon (exponent e)))
                (if (number? expon) (make-exp (base e) (- expon 1))
                    (make-exp (base e) (list '- expon 1)))))    
        (define (deriv exp var)
          (cond ((number? exp) 0)
                ((variable? exp)
                 (if (same-variable? exp var) 1 0))
                ((sum? exp)
                 (make-sum (deriv (addend exp) var)
                           (deriv (augend exp) var)))
                ((product? exp)
                 (make-sum
                   (make-product (multiplier exp)
                                 (deriv (multiplicand exp) var))
                   (make-product (deriv (multiplier exp) var)
                                 (multiplicand exp))))
                ;对幂的处理
                ((is-exp? exp)
                  (make-product (make-product (exponent exp) (exponent-dec exp)) 
                  (deriv (base exp) var))    
                )
                (else
                 (error "unknown expression type -- DERIV" exp))))
        
        ;ex 2.57
        (define (augend s)
            (if (> (length (cddr s)) 1) (append (list '+) (cddr s))
                (caddr s)))
        (define (multiplicand p)
                (if (> (length (cddr p)) 1) (append (list '*) (cddr p))
                (caddr p)))
        ;ex 2.58        
        ;中缀表示
        (define (sum? x)
          (and (pair? x) (eq? (cadr x) '+)))
        (define (addend s) (car s))
        (define (augend s)        
            (if (> (length (cddr s)) 1) (cddr s)
                (caddr s)))
    
        (define (product? x)
          (and (pair? x) (eq? (cadr x) '*)))
        (define (multiplier p) (car p))
        (define (multiplicand p)            
            (if (> (length (cddr p)) 1) (cddr p)
                (caddr p)))
        
        (define (make-sum a1 a2)
          (cond ((=number? a1 0) a2)
                ((=number? a2 0) a1)
                ((and (number? a1) (number? a2)) (+ a1 a2))
                (else (list a1 '+ a2))))
    
        (define (make-product m1 m2)
          (cond ((or (=number? m1 0) (=number? m2 0)) 0)
                ((=number? m1 1) m2)
                ((=number? m2 1) m1)
                ((and (number? m1) (number? m2)) (* m1 m2))
                (else (list m1 '* m2))))    
        ;(deriv '(x * y * (x + 3)) 'x)
        ;(deriv '(x + 3 * (x + y + 2))
    )
  • 相关阅读:
    人类历史上最智慧的169条警世箴言(句句珠玑,发人深省)
    最负责任的回答
    成大事必须依靠的五种人
    一生的伤痕
    有谁愿意陪我一程
    惜缘
    那朵美丽的格桑花,你是否依然绽放?
    今生今世只等你
    成就一生的15条黄金法则
    遇到困难挫折也不要悲观:每个人生来就是冠军(转)
  • 原文地址:https://www.cnblogs.com/sniperHW/p/3093820.html
Copyright © 2020-2023  润新知