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 @   再思即可  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示