【问题标题】:Postfix calculation in smalltalksmalltalk中的后缀计算
【发布时间】:2013-04-04 20:22:36
【问题描述】:

我必须编写代码来评估 Smalltalk 中的后缀符号(反向波兰评估)。我已经阅读了文档并且还实现了一个堆栈。这是我目前写的代码:

Object subclass: #Rpcalc
instanceVariableNames: 'anArray top'
classVariableNames: ''
poolDictionaries: ''
category: nil !

pop:
    | item |
item := anArray at: top.
top := top - 1.
^item!

push: item
 top := top + 1.
 anArray at: top put: item!

setsize: n
  anArray := Array new: n.
  top := 0! 

evaluate:
       | expression aToken op1 op2 operator answer|
   Transcript show: 'Enter Expression' .
   expression :- stdin nextLine.

   | aStack |
   aStack := Array new: 10 .

   aToken := self getNextToken.
       ((aToken key) = 'operand')
       ifTrue: [push : aToken].

        aToken := self getNextToken.
       ((aToken key) = 'operator')
        ifTrue:  [op1 := pop.
           op2 := pop.
           operator := aToken.
   "if(operator := +)"
   "answer := op1 + op2"

我想知道如何标记表达式中的每个元素。例如, 对于表达式, 10 3 + 3 7 * - 我需要把它等同于一个令牌。如果它是一个操作数,它应该将它压入堆栈。如果是运算符,则弹出堆栈两次以获取操作数并计算表达式。我对 smalltalk 完全陌生,所以我对语法一无所知。

【问题讨论】:

    标签: smalltalk postfix-notation


    【解决方案1】:

    您没有指定您使用的是哪种 Smalltalk 方言。在 Squeak 中,您可以使用 findTokens: 方法:

    '336 8 4 2 1 + - * /' findTokens: ' '
    ==> an OrderedCollection('336' '8' '4' '2' '1' '+' '-' '*' '/')
    

    使用isDigit 测试令牌是否为数字:

    '336' first isDigit
    ==> true
    '+' first isDigit
    ==> false
    

    要将字符串转换为数字,您可以使用asNumber

    '336' asNumber
    ==> 336
    

    整个 RPN 解析器/评估器可以用不到 10 行代码轻松实现,但显然这是你要做的功课(提示:无需实现堆栈,已经有一个)。

    【讨论】:

      【解决方案2】:

      我建议你看看PetitParser。您可以将您拥有的表达式:10 3 + 3 7 * 解析为令牌,例如:NumberToken(10)、OperatorTocken(+),然后根据您需要的令牌进行操作。也不要这样做

      operator = '+' ifTrue: [op1 + op2]
      

      做:

      op1 perform: operator with: op2
      

      相反,

      【讨论】:

      • 使用#perform: 是只有在 (a) 您是一位经验丰富的 Smalltalker 并且 (b) 您绝对必须这样做的情况下才应该这样做。它会破坏内省,很容易让你的生活陷入地狱。对于这样的解释器,我会说不要使用#perform:with:。通过显式检查,您可以一目了然地看到支持的操作。
      猜你喜欢
      • 2018-03-20
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 2021-05-25
      • 2012-04-05
      • 2012-04-11
      • 2016-07-10
      • 2012-06-26
      相关资源
      最近更新 更多