Scheme 在racket中使用调度表
我正在编写一个小程序来计算以列表形式表示的表达式的简单导数,即Scheme 在racket中使用调度表,scheme,racket,Scheme,Racket,我正在编写一个小程序来计算以列表形式表示的表达式的简单导数,即2x^2表示为(*2(exp x 2)),我定义了以下函数: ;; derivative of a constant is 0 (define (diff-constant x E) 0) ;; computes derivative of E with respect to x where E can only be of the form ;; (+ x x ...) (define (diff-sum x E) (cond
2x^2
表示为(*2(exp x 2))
,我定义了以下函数:
;; derivative of a constant is 0
(define (diff-constant x E) 0)
;; computes derivative of E with respect to x where E can only be of the form
;; (+ x x ...)
(define (diff-sum x E)
(cond ((or (not (list? E)) (null? E)) 0)
((eq? (car E) x) (+ 1 (diff-sum x (cdr E))))
(else (diff-sum x (cdr E)))))
;; computes derivative of E with respect to x where E can only be of the form
;; (* x y)
(define (diff-product x E)
(cond ((and (eq? x (cadr E)) (eq? x (caddr E))) (list '* 2 x))
((eq? x (cadr E)) (list (caddr E)))
((eq? x (caddr E)) (list (cadr E)))
(else 0)))
;; computes derivative of E with respect to x where E can only be of the form
;; (expt x y) which is x^y
(define (diff-expt x E)
(cond ( not (eq? x (cadr E)) 0)
((eq? 1 (caddr E)) 0)
((eq? 2 (caddr E)) (cadr E))
(else (list '* (caddr E) (list 'expt x (- (caddr E) 1))))))
我还有一个调度表,定义为:
;; Dispatch Table of supported operators.
(define diff-dispatch
(list (list '+ diff-sum)
(list '* diff-product)
(list 'expt diff-expt)
))
我正在尝试编写一个函数diff
,它接受一个等式E
(以列表形式),计算关于x
的导数,并使用分派表调用返回结果的预定义函数
这是我到目前为止得到的,但我不知道剩下的是什么
;; Differentiate expression E with respect to x.
(define (diff x E)
(cond ((number? E) (diff-constant x E))
;; insert code here to handle the other base case - variables
...
(else ; insert code here to lookup the appropriate function in the
; dispatch table based on the operator in the expression,
; then call that function to differentiate the expression
(diff-func x E))))))
例:(diff'x'(+x(*x)))
应计算为(+1(+1(*x))(*x 1))
(即1+x+x)在中有一整节详细解释了如何构建用于执行符号微分的Scheme程序,请参阅。特别要注意的是,您缺少一种情况—如果要派生的表达式是变量,会发生什么情况?检查链接以确保你在正确的轨道上
现在,回答这个问题:给定代码中使用的表表示,实现调度器很简单。通过应用正确的鉴别程序,这些方法将有助于获得正确的鉴别结果:
((cadr ; obtain the differentiation procedure
(assoc ; look for the differentiation procedure
(car E) ; obtain the operator in the expression
diff-dispatch)) ; dispatch table
x E) ; apply the procedure with parameters `x` and `E`
请注意,查找要应用的正确过程的“诀窍”在于,该表是作为关联列表实现的,而
assoc
过程正是为了在这样的列表中查找数据而设计的。在。中阅读更多关于它的信息,以补充Óscar López的回答:在专业水平的球拍项目中,我们希望尽快发送。如果要测试的内容数量超过了几个项目,我们可能应该使用支持快速查找的数据结构,例如向量或。数据表示可能很重要:列表不是我们应该知道的最好或唯一的数据结构。SICP倾向于对所有事物使用链表表示法,这是值得称赞的。但有时链表不是正确的结构
在基于哈希表的方法中,调度表的设置非常相似:
;; in professional-level Racket (#lang racket)
(define dispatch-table (hash '+ diff-sum
'* diff-product
;; ... etc
))
查找表是一个非常困难的过程
(define op '+)
(hash-ref dispatch-table op) ;;; => diff-sum