sicp每日一题[2.79]

Exercise2.79

Define a generic equality predicate equ? that tests the equality of two numbers, and install it in the generic arithmetic package. This operation should work for ordinary numbers, rational numbers, and complex numbers.


这道题也挺简单的,分别在一般数字、有理数和复数包里实现这个函数就行了,以下代码复数部分在 2.77 的基础上添加,一般数字和有理数在书上 2.5.1 的基础上添加

(define (equ? x y) (apply-generic 'equ? x y))

; 一般数字
(put 'equ? '(scheme-number scheme-number) =)

; 有理数
(define (equ? x y)
  ;; 先化简为最简有理数
  (let ((simple-x (make-rat (numer x) (denom x)))
        (simple-y (make-rat (numer y) (denom y))))
    (and (= (numer simple-x) (numer simple-y))
         (= (denom simple-x) (denom simple-y)))))

(put 'equ? '(rational rational)
     (lambda (x y) (equ? x y)))

; 复数,只用在 install-complex-package 里添加就行
(define (equ? z1 z2)
  (and (= (real-part z1) (real-part z2))
       (= (imag-part z1) (imag-part z2))))

(put 'equ? '(complex complex)
     (lambda (z1 z2) (equ? z1 z2)))


; 测试
(install-scheme-number-package)
(define n1 (make-scheme-number 5))
(define n2 (make-scheme-number 10))
(define n3 (make-scheme-number 10))
(equ? n1 n2)
(equ? n2 n3)

(newline)
(install-rational-package)
(define r1 (make-rational 5 5))
(define r2 (make-rational 10 10))
(define r3 (make-rational 10 20))
(equ? r1 r2)
(equ? r2 r3)

(newline)
(install-rectangular-package)
(install-polar-package)
(install-complex-package)
(define z1 (make-complex-from-real-imag 3 4))
(define z2 (make-complex-from-real-imag 3 4))
(define z3 (make-complex-from-real-imag 3 5))
(equ? z1 z2)
(equ? z2 z3)

; 结果如下
'done
#f
#t

'done
#t
#f

'done
'done
'done
#t
#f

看了一下别人的答案,有理数部分可以通过十字相乘来使得答案更简单。

(define (equ? x y) 
   (= (* (numer x) (denom y)) (* (numer y) (denom x)))) 
posted @ 2024-11-16 13:23  再思即可  阅读(1)  评论(0编辑  收藏  举报