SICP 全笔记

Exercise 2.89. Define procedures that implement the term-list representation described above as appropriate for dense polynomials.

对于 dense 多项式,我们需要想办法做到的是只修改其底层表示的数据结构而不更改其余部分。

所以我们要保留所有在过程中使用到的选择函数与构造函数,然后还需要修改 adjoin-term。

  ;; representation for dense polynomials
  (define (adjoin-term term term-list)
    (cond ((=zero? (coeff term))
           term-list)
          ((= (order term) (length term-list))
           (cons (coeff term) term-list))
          (else
           (adjoin-term term (cons 0 term-list)))))

  (define (the-empty-termlist) '())
  (define (first-term term-list)
    (list (- (length term-list) 1) (car term-list)))
  (define (rest-terms term-list) (cdr term-list))
  (define (empty-termlist? term-list) (null? term-list))
  (define (make-term order coeff) (list order coeff))
  (define (order term) (car term))
  (define (coeff term) (cadr term))

以上内容主要修改了 first-termadjoin-term。举例来说,对于 (1 0 0 0 0 1) 来表示的 $x^5 + 1$first-term 会得到 (5 1) 表示这个 first-term 是 5 次方,系数为 1。其余的过程可以不变。

adjoin-term 稍微复杂一点,因为它需要去补全不存在的次方数的系数,使每个计算出的结果都保持 dense 的状态。

这两个过程调整之后,新的多项式系统就能处理 dense 表示的多项式了。

(load "../testframe.scm")

(asserttrue (=zero? (make-polynomial 'x '(0 0 0 0 0))))

(asserteq? false (=zero? (make-polynomial 'x '(1 0 0 0 0 0))))

; x^3 + (x^3 + x^1 + 1)
(assertequal? (add (make-polynomial 'x '(1 0 0 1))
                   (make-polynomial 'x '(1 0 1 1)))
              (make-polynomial 'x '(2 0 1 2)))

; [(y^3+4)x^2] + [(2y^3 + 5)x^2 ]
; = [(3y^3+9)x^2
(assertequal? (add (make-polynomial
                    'x
                    (list (make-polynomial 'y '(1 0 0 4))
                          0
                          0))
                   (make-polynomial
                    'x
                    (list (make-polynomial 'y '(2 0 0 5)) 0 0)))
              (make-polynomial
               'x
               (list (make-polynomial 'y '(3 0 0 9))
                     0
                     0)))


; raise Error here: (y + 3) + 0 => raise error

; [(y^3+4)x^2 + (y+3)x] + [(2y^3 + 5)x^2]
; = [(3y^3+9)x^2 + (y+3)x
;; (assertequal? (add (make-polynomial
;;                     'x
;;                     (list (make-polynomial 'y '(1 0 0 4))
;;                           (make-polynomial 'y '(1 3))
;;                           0))
;;                    (make-polynomial
;;                     'x
;;                     (list (make-polynomial 'y '(2 0 0 5)) 0 0)))
;;               (make-polynomial
;;                'x
;;                (list (make-polynomial 'y '(3 0 0 9))
;;                      (make-polynomial 'y '(1 3))
;;                      0)))

; (x^5 + 1) x^3 = (x^8 + x^3)
(assertequal? (mul (make-polynomial 'x '(1 0 0 0 0 1))
                   (make-polynomial 'x '(1 0 0 0)))
              (make-polynomial 'x '(1 0 0 0 0 1 0 0 0)))

但这里有的问题是,dense 多项式在计算系数的时候需要计算诸如 (y+3) + 0 这样的表达式。在我们目前的系统中,并没有将 polynomial 添加到 raise 中,所以这样的计算是会出错的。