Scheme程序没有评估嵌套列表?

时间:2017-04-11 16:50:39

标签: scheme racket r5rs

我正在编写一个方案程序,该程序在最后用操作员评估列表。

示例:(评估'(1 2 +)) - > 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)))))))))

2 个答案:

答案 0 :(得分:1)

我有三个指点:

如果其中一个参数是表达式,则表示您没有对其进行评估。从而。你需要在两个参数上运行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

请注意,这里的参数实际上是自动计算的。这就是连接语言(也就是堆栈语言)的用法。

答案 1 :(得分:0)

您忘记以递归方式调用子表达式上的过程。请参阅此处,我已将其重命名为!以简化:

(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)))))))