在Scheme中简单的计算器程序的麻烦

时间:2013-10-01 19:51:37

标签: scheme racket calculator

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

#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非常新,所以非常感谢任何帮助

2 个答案:

答案 0 :(得分:2)

代码中的语法不正确。正如您对问题的评论所指出的那样,您错误地放了一些问题。在Scheme中,通过一致地缩进来“跟踪parens”可以获得很大的好处。这是一个让你大部分都在那里的版本。

(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

答案 1 :(得分:0)

为了转换

  

1 - 2 + 3

  

( - 1(+ 2 3))

你需要

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

    1)list of end =>返回缓存值

    否则在

    之间切换

    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