跳至內容

Scheme 程式設計/抽象與資料

來自華夏公益教科書,開放書籍,開放世界

複數介紹

[編輯 | 編輯原始碼]

為了展示如何構建資料抽象,我們將逐步建立一個複數包。複數包含兩個部分,實部和虛部。它們通常以兩種方式之一表示,直角座標形式

和極座標形式

現在,我們可以對複數執行所有常見的算術運算,加法、減法、乘法和除法。它們有簡單的公式;

加法

減法

乘法

除法

請注意,乘法和除法最好用極座標形式表示,而加法和減法最好用直角座標形式表示。這就提出了一個有趣的問題:如何最好地計算這些?我們是否使用一種內部表示?如果是,我們選擇哪一種?有很多問題需要解決。這些可以透過嘗試實現一種新的資料型別來解決:複數型別。

建立我們的通用“型別”變數

[編輯 | 編輯原始碼]

首先,我們將建立一個通用“型別”變數

(define typed-variable
  (lambda (type value)
    (cons 'Typed (list type value))
  )
)

現在我們需要一種方法來判斷給定變數是否具有型別

(define typed?
  (lambda (var)
    (and (list? var) (= 'Typed (car var)))
  )
)

現在,我們已經引入了兩個重要的概念,“謂詞”和“建構函式”。第一個是用於判斷某些資料是否具有正確形式的結構,第二個是用於構建我們資料結構的程式。

我們必須有一種方法來提取我們的資料(在本例中,是型別)從這種結構中,一種“選擇”它的方法

(define type-of
  (lambda (var)
    (if (typed? var)
      (car (cdr var)
    )
  )
)

建立我們的複數資料型別

[編輯 | 編輯原始碼]

構建我們的建構函式

[編輯 | 編輯原始碼]

使用此型別的值,我們可以繼續為我們的複數形成更詳細的資料結構

(define complex-rect
  (lambda (a b)
    (typed-variable 'Rect-Complex (list a b))
  )
)

現在讓我們繼續,並建立一個complex-polar

(define complex-polar
  (lambda (r thet)
    (typed-variable 'Polar-Complex (list r thet))
  )
)
(define complex
  (lambda (type first-var second-var)
    (if (equal? 'type Polar)
        (cons (complex-polar first-var second-var) 
              (complex-rect (sqrt (+ (expt first-var 2) 
                                     (expt second-var 2)
                                  )
                            ) 
                            0
              )
        )  ;; Change second half to be the calculated values.
        (cons (complex-polar 0 0) (complex-rect first-var second-var))
    )
  )
)

構建我們的謂詞

[編輯 | 編輯原始碼]

我們擁有了建構函式,現在我們需要謂詞

(define is-complex?
  (lambda (var)
    (and (typed? (car var)) 
         (or (= 'Rect-Complex (type-of (car var))) 
             (= 'Polar-Complex (type-of (car var)))
         )
    )
  )
)


現在我們可以根據這些程式定義算術運算。

華夏公益教科書