我正在编写一个计划程序,它与操作符一起评估一个列表的末尾。
例子:(评估‘(12+)->3
我的函数可以用于基本运算符(+,-,*,/),但是当我有一个嵌套列表时,问题就出现了。
例子:(评估'(1 (2 3 +) *)) ->(无)
我错过了条件吗?
(define (evaluate lis)
(cond
((not (list? lis))
lis)
((list? lis)
(if (equal? (length lis) 3)
(cond
((equal? (cddr lis) '(+))
(+ (car lis) (car (cdr lis))))
((equal? (cddr lis) '(-))
(- (car lis) (car (cdr lis))))
((equal? (cddr lis) '(*))
(* (car lis) (car (cdr lis))))
((equal? (cddr lis) '(/))
(/ (car lis) (car (cdr lis)))))))))发布于 2017-04-11 16:56:14
您忘记递归地调用子表达式上的过程。请参阅此处,为了简洁起见,我已将其重命名为!:
(define (! lis)
(cond
((not (list? lis))
lis)
((list? lis)
(if (equal? (length lis) 3)
(cond
((equal? (cddr lis) '(+))
(+ (! (car lis)) (! (cadr lis))))
((equal? (cddr lis) '(-))
(- (! (car lis)) (! (cadr lis))))
((equal? (cddr lis) '(*))
(* (! (car lis)) (! (cadr lis))))
((equal? (cddr lis) '(/))
(/ (! (car lis)) (! (cadr lis)))))))))顺便提一句,下面是您如何更愚蠢地重写程序:
(define (evaluate lis)
(cond
((not (list? lis)) lis)
((= (length lis) 3)
(let ((op (case (caddr lis)
((+) +)
((-) -)
((*) *)
((/) /))))
(op (evaluate (car lis)) (evaluate (cadr lis)))))))发布于 2017-04-11 17:15:34
我有三个建议:
如果其中一个参数是表达式,则不计算它。因此。您还需要对这两个参数运行postfix。
当长度不是3时,让实现选择if应该返回的值。为了拍它的#<void>。也许你该选点什么?
由于您的单词有固定数量的参数,所以没有必要使用括号:
(define (peval exprs)
(define primitives `((+ . ,+) (- . ,-) (* . ,*) (/ . ,/)))
(foldl (lambda (operator operands)
(let ((aproc (assq operator primitives)))
(if aproc
(cons ((cdr aproc) (cadr operands) (car operands))
(cddr operands))
(cons operator operands))))
'()
exprs))
(peval '(2 3 4 + *)) ; (2 (3 4 +) *) == 14注意,这里的参数实际上是自动计算的。连接语言(也称为堆栈语言)就是这样做的。
https://stackoverflow.com/questions/43351910
复制相似问题