計算機程序的構造和解釋 練習題2.89

主要修改多項式這裏的過程

(define (add-terms L1 L2)
  (cond ((empty-termlist? L1) L2)
        ((empty-termlist? L2) L1)
        (else
         (let ((t1 (first-term L1)) (t2 (first-term L2)))
           (cond ((> (order L1) (order L2))
                 (adjoin-term
                  t1 (add-terms (rest-terms L1) L2)))
                 ((< (order L1) (order L2))
                  (adjoin-term
                   t2 (add-terms L1 (rest-terms L2))))
                 (else
                  (adjoin-term
                   (add (coeff L1) (coeff L2))
                   (add-terms (rest-terms L1)
                              (rest-terms L2)))))))))
(define (sub-terms L1 L2)
  (cond ((empty-termlist? L1) L2)
        ((empty-termlist? L2) L1)
        (else
         (let ((t1 (first-term L1)) (t2 (first-term L2)))
           (cond ((> (order L1) (order L2))
                 (adjoin-term
                  t1 (sub-terms (rest-terms L1) L2)))
                 ((< (order L1) (order L2))
                  (adjoin-term
                   t2 (sub-terms L1 (rest-terms L2))))
                 (else
                  (adjoin-term
                   (sub (coeff L1) (coeff L2))
                   (sub-terms (rest-terms L1)
                              (rest-terms L2)))))))))
(define (mul-terms L1 L2)
  (if (empty-termlist? L1)
      (the-empty-termlist)
      (add-terms (mul-term-by-all-terms L1 L2)
                 (mul-terms (rest-terms L1) L2))))
  
(define (mul-term-by-all-terms L1 L2)
  (if (empty-termlist? L2)
      (if (= (length L1) 1) (the-empty-termlist) (make-term-list (- (order L1) 1) 0))
      (let ((t1 (first-term L1))
            (t2 (first-term L2)))
        (adjoin-term
         (mul t1 t2)
         (mul-term-by-all-terms L1 (rest-terms L2))))))
(define (adjoin-term term term-list)
      (cons term term-list))
(define (the-empty-termlist) '())
(define (first-term term-list) (car term-list))
(define (rest-terms term-list) (cdr term-list))
(define (empty-termlist? term-list) (null? term-list))
(define (make-term-list order coeff) 
  (define (iter n term-list)
    (if (= n order) (cons coeff term-list)
          (iter (+ n 1) (cons 0 term-list))))
  (iter 0 '()))
(define (order term-list) (- (length term-list) 1))
(define (coeff term-list) (car term-list))

完整過程

#lang racket
;put get實現
(define *op-table* (make-hash))

(define (put op type proc)
  (hash-set! *op-table* (list op type) proc))

(define (get op type)
  (hash-ref *op-table* (list op type) #f))

(define (attach-tag type-tag contents)
  (cond ((eq? type-tag 'scheme-number) contents)
        (else (cons type-tag contents))))

(define (type-tag datum)
  (cond ((number? datum) 'scheme-number)
        ((pair? datum) (car datum))
        (else (error "Bad tagged datum -- TYPE-TAG" datum))))

(define (contents datum)
   (cond ((number? datum) datum)
         ((pair? datum) (cdr datum))
         (else (error "Bad tagged datum -- CONTENTS" datum))))

(define (apply-generic op . args)
  (let ((type-tags (map type-tag args)))
    (let ((proc (get op type-tags)))
      (if proc
          (apply proc (map contents args))
          (error "No method for these types"
                                (list op type-tags))))))

(define (add x y) (apply-generic 'add x y))
(define (sub x y) (apply-generic 'sub x y))
(define (mul x y) (apply-generic 'mul x y))
(define (div x y) (apply-generic 'div x y))
(define (=zero? x) (apply-generic '=zero? x))



(define (install-scheme-number-package)
  (define (tag x)
    (attach-tag 'scheme-number x))
  (put 'add '(scheme-number scheme-number)
       (lambda (x y) (tag (+ x y))))
  (put 'sub '(scheme-number scheme-number)
       (lambda (x y) (tag (- x y))))
  (put 'mul '(scheme-number scheme-number)
       (lambda (x y) (tag (* x y))))
  (put 'div '(scheme-number scheme-number)
       (lambda (x y) (tag (/ x y))))
  (put '=zero? '(scheme-number)
       (lambda (x) (= x 0)))
  (put 'make 'scheme-number
       (lambda (x) (tag x)))
  'done)
(define (make-scheme-number n)
  ((get 'make 'scheme-number) n))

(define (install-polynomial-package)
  (define (make-poly variable term-list)
    (cons variable term-list))
  (define (variable p) (car p))
  (define (term-list p) (cdr p))
  (define (add-poly p1 p2)
    (if (same-variable? (variable p1) (variable p2))
        (make-poly (variable p1)
                   (add-terms (term-list p1)
                              (term-list p2)))
        (error "Poly not in same var -- ADD-POLY"
               (list p1 p2))))
  (define (sub-poly p1 p2)
    (if (same-variable? (variable p1) (variable p2))
        (make-poly (variable p1)
                   (sub-terms (term-list p1)
                              (term-list p2)))
        (error "Poly not in same var -- SUB-POLY"
               (list p1 p2))))
  (define (mul-poly p1 p2)
    (if (same-variable? (variable p1) (variable p2))
        (make-poly (variable p1)
                   (mul-terms (term-list p1)
                              (term-list p2)))
        (error "Polys not in same var -- MUL-POLY"
               (list p1 p2))))
  
  (define (=zero-poly? poly)
    (define (coeff-all-zero? term-list)
      (if (empty-termlist? term-list)
          #t
          (if (=zero? (coeff (first-term term-list)))
              (coeff-all-zero? (rest-terms term-list))
              #f)))
    (coeff-all-zero? (term-list poly)))
  (define (tag p) (attach-tag 'polynomial p))
  (put 'add '(polynomial polynomial)
       (lambda (p1 p2) (tag (add-poly p1 p2))))
  (put 'mul '(polynomial polynomial)
       (lambda (p1 p2) (tag (mul-poly p1 p2))))
  (put 'sub '(polynomial polynomial)
       (lambda (p1 p2) (tag (sub-poly p1 p2))))
  (put '=zero? '(polynomial) =zero-poly?)
  (put 'make 'polynomial
       (lambda (var terms) (tag (make-poly var terms))))
  'done)
(define (add-terms L1 L2)
  (cond ((empty-termlist? L1) L2)
        ((empty-termlist? L2) L1)
        (else
         (let ((t1 (first-term L1)) (t2 (first-term L2)))
           (cond ((> (order L1) (order L2))
                 (adjoin-term
                  t1 (add-terms (rest-terms L1) L2)))
                 ((< (order L1) (order L2))
                  (adjoin-term
                   t2 (add-terms L1 (rest-terms L2))))
                 (else
                  (adjoin-term
                   (add (coeff L1) (coeff L2))
                   (add-terms (rest-terms L1)
                              (rest-terms L2)))))))))
(define (sub-terms L1 L2)
  (cond ((empty-termlist? L1) L2)
        ((empty-termlist? L2) L1)
        (else
         (let ((t1 (first-term L1)) (t2 (first-term L2)))
           (cond ((> (order L1) (order L2))
                 (adjoin-term
                  t1 (sub-terms (rest-terms L1) L2)))
                 ((< (order L1) (order L2))
                  (adjoin-term
                   t2 (sub-terms L1 (rest-terms L2))))
                 (else
                  (adjoin-term
                   (sub (coeff L1) (coeff L2))
                   (sub-terms (rest-terms L1)
                              (rest-terms L2)))))))))
(define (mul-terms L1 L2)
  (if (empty-termlist? L1)
      (the-empty-termlist)
      (add-terms (mul-term-by-all-terms L1 L2)
                 (mul-terms (rest-terms L1) L2))))
  
(define (mul-term-by-all-terms L1 L2)
  (if (empty-termlist? L2)
      (if (= (length L1) 1) (the-empty-termlist) (make-term-list (- (order L1) 1) 0))
      (let ((t1 (first-term L1))
            (t2 (first-term L2)))
        (adjoin-term
         (mul t1 t2)
         (mul-term-by-all-terms L1 (rest-terms L2))))))
(define (adjoin-term term term-list)
      (cons term term-list))
(define (the-empty-termlist) '())
(define (first-term term-list) (car term-list))
(define (rest-terms term-list) (cdr term-list))
(define (empty-termlist? term-list) (null? term-list))
(define (make-term-list order coeff) 
  (define (iter n term-list)
    (if (= n order) (cons coeff term-list)
          (iter (+ n 1) (cons 0 term-list))))
  (iter 0 '()))
(define (order term-list) (- (length term-list) 1))
(define (coeff term-list) (car term-list))
(define (make-polynomial var terms)
  ((get 'make 'polynomial) var terms))

(define (same-variable? v1 v2)
  (define (variable? x) (symbol? x))
  (and (variable? v1) (variable? v2) (eq? v1 v2)))
(install-scheme-number-package)
(install-polynomial-package)
(define polynumial-A (make-polynomial 'x '(5 2 4 5 6 7)))
(define polynumial-B (make-polynomial 'x '(5 2 4 5 6 7)))
(define polynumial-C (make-polynomial 'x '(2 1)))
(add polynumial-A polynumial-B)
(sub polynumial-A polynumial-B)
(mul polynumial-B polynumial-C)
                                 

運行結果

'done
'done
'(polynomial x 10 4 8 10 12 14)
'(polynomial x 0 0 0 0 0 0)
'(polynomial x 10 9 10 14 17 20 7)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章