2017-04-11 27 views
0

我正在编写一个计划程序,最终对操作员列表进行评估。计划程序不评估嵌套列表吗?

实施例:(评价“(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))))))))) 

回答

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))))))) 
+0

哦,我现在看到了问题。我由于某种原因认为我的发言彻底解决了。我完全忘了递归调用该函数。我对Scheme很陌生,所以看看列表如何在这里工作很有趣。谢谢! – Disc0nnect

1

我有3个指针:

如果一个的论点是你没有评估它的表达。从而。你也需要在两个参数上运行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 

注意,这里实际上得到的参数自动计算。这就是连接语言(又名堆栈语言)如何做到的。