0

我需要为 Scheme 中的简单算术表达式定义一个计算器。例如,当键入 时(calculator '( 1 + 2)),方案解释器将打印3. 计算器将接受任何长度的表达式,并且表达式关联到右侧。例如,在(calculator '(1 + 1 - 2 + 3 ))表达式中被解释为(1 + (1 - (2 + 3))),因此值为-3。我假设表达式只有+and-运算符,并且输入中没有括号。到目前为止,我编写了这个程序:

#lang lazy
(define (calculator exp)
 (cond
   ((null? exp) 0)
   (= (length (exp)) 1 exp)
   (eq? '+ (cdr (cdr exp)) (+ (car exp) (calculator (cdr (cdr exp)))))
   (else (eq? '- (cdr (cdr exp)) (- (car exp) (calculator (cdr (cdr exp)))))))

但是当我尝试类似的东西时(calculator '(1 + 1 + 1)),我得到了这个错误:

#%module-begin: allowed only around a module body in: (#%module-begin (define
(calculator exp) (cond ((null? exp) 0) (= (length (exp)) 1 exp) (eq? (quote +)
(cdr (cdr exp)) (+ (car exp) (calculator (cdr (cdr exp))))) (else (eq? (quote -)
(cdr (cdr exp)) (- (car exp) (calculator (cdr (cdr exp)))))))) (calculator
(quote (1 + 1 + 1))))

我对 Scheme 很陌生,因此我们将不胜感激任何帮助

4

2 回答 2

2

您的代码中的语法不正确。正如对您问题的评论中所述,您放错了一些括号。在 Scheme 中,通过一致缩进,您在“跟踪括号”方面获得了很大的好处。这是一个可以让您大部分时间到达那里的版本。

(define (calculator exp)
  (cond ((null? exp) 0)                 ; zero terms
        ((null? (cdr exp)) (car exp))   ; one  term only (assumed number)
        (else                           ; assumed three or more terms
          (let ((operand1 (car  exp))
                (operator (cadr exp))
                (operands (cddr exp)))
            ((case operator             ; convert operator, a symbol, to its function
               ((+) +)
               ((-) -))
             operand1
             (calculator operands)))))) ; calculate the rest
> (calculator '(1 + 2))
3
> (calculator '(1 - 2 + 3))
-4
于 2013-10-02T06:01:36.147 回答
0

为了转换

1 - 2 + 3

(- 1 (+ 2 3))

你需要

  1. 缓存值 1
  2. apply - 缓存值 1 和表达式的其余部分
  3. 缓存值 2
  4. 将 + 应用于缓存值 2 和表达式的其余部分
  5. 缓存值 3
  6. 返回缓存值 3,因为您的列表现在为空

所以你有3个案例:

1) 列表结尾 => 返回缓存值

否则在

2)缓存一个值

3) 将函数应用于缓存值和表达式的其余部分

示例代码:

(define (calculator exp)
  (define funcs (hasheq '+ + '- -))
  (let loop ((exp exp) (toggle #t) (val #f))
    (if (empty? exp)
        val ; 1) end of list => return cached value
        (if toggle
            (loop (cdr exp) #f (car exp)) ; 2) cache value
            ((hash-ref funcs (car exp)) val (loop (cdr exp) #t #f)))))) ; 3) apply the function to the cached value and the rest of the expression
于 2013-10-02T21:11:51.510 回答