2012-10-16 44 views
1

这是到目前为止我的代码:后缀计算器,如何处理连续3个数字?

public class PostfixCalculator { 

    private Stack<Float> stack; 
    private float result; 

    private Boolean isOperator (char op){ 
    boolean operator; 
    switch (op){ 
     case '+': 
     case '-': 
     case '*': 
     case '/': 
     case '^': 
      operator = true; 
      break; 
    default: 
     operator = false; 
     break;} 
    return operator; 
} 

private Boolean isFunction (String func){ 
    String[] functions = {"sin", "cos", "max"}; 
    for (int i=0; i<functions.length; i++){ 
     if (func.equals(functions[i])) 
      return true; } 
    return false; 
} 

private void computeOperator (float op1, float op2, char op){ 
    switch (op){ 
     case '+': 
      result = op1 + op2; 
      break; 
     case '-': 
      result = op1 - op2; 
      break; 
     case '/': 
      result = op1/op2; 
      break; 
     case '*': 
      result = op1 * op2; 
      break; 
     case '^': 
      result = (float) Math.pow(op1, op2); 
      break; 

     default: 
      break; 
    } 
} 

public float calculate(String expr) throws IllegalArgumentException { 
    result = 0; 
    String token; 
    Float makeit; 
    char operator; 
    float op1, op2, pushFloat; 
    StringTokenizer calc=new StringTokenizer(expr); 

    stack = new Stack<Float>(); 

    while (calc.hasNextToken()){ 
     token=calc.getNextToken(); 
     operator=token.charAt(0); 

     if (!(this.isOperator(operator))){ 
      if (this.isFunction(token)){ 
       if (token.equals("sin")){ 
        op1=stack.pop(); 
        result = (float) Math.sin(op1); 
        stack.push(result); 
       } 
       else if (token.equals("cos")){ 
        op1=stack.pop(); 
        result = (float) Math.cos(op1); 
        stack.push(result); 
       } 
       else if (token.equals("max")){ 
        op1=stack.pop(); 
        op2=stack.pop(); 
        result=Math.max(op1, op2); 
        stack.push(result); 
       } 

      } 
      else { 
       makeit = new Float(token); 
       pushFloat = makeit.floatValue(); 
       stack.push(pushFloat); 
      } 

     } 
     else { 
      op1 = stack.pop(); 
      op2 = stack.pop(); 
      computeOperator (op1, op2, operator); 
      stack.push(result); 


     } 
    } 
    return stack.pop(); 
} 

}

我想我有下来的基础,但如何处理后缀的计算与连续三位数以上,像例如'2 3 4 * - '?任何帮助,将不胜感激。提前致谢!

+0

为了保持一致性/可理解性,'result'应该是本地的,'computeOperator'应该返回一个你赋给'result'的值。 –

+0

并且有两个功能 - computeMonadic和computeDiadic。在computeDiadic中处理max和你的“操作符”。将isOperator替换为isMonadic或isDiadic。 (不需要使用charAt - 只需将所有运算符/函数名称视为字符串即可。) –

+0

如果想要使用charAt,可以使用'Operator'类或类似方法,并为每个运算符/函数创建子类。构建一个Operator子类和索引的数组以查找您的操作。 (但这将是“额外的功劳”)。 –

回答

1

是的,一个堆栈。我们可以很容易地使用数组和计数器来实现一个简单的堆栈 - 不需要使用花哨的类。

该数组的大小与您可以处理的最深层嵌套表达式(10个元素应该足以满足几乎所有“真实”问题)一样大。

推动更新A [i]并增加i。流行音乐是递减我和参考A [我]。 “8 9 +”是按下(8),按下(9),弹出顶部的两个元素,添加它们,按下结果。请注意,操作符永远不会被推送,只有操作数/结果。 '将会推(2),推(3),推(4),弹出顶部2,乘,推结果,弹出2,减1,推结果。

“7 6 + cos”将被按下(7),按下(6),弹出两个按钮,添加按下结果,弹出一个按钮,执行“cos”,按下结果。

如果您需要弹出某个元素并且计数器为零(例如,“7 +” - 您想要弹出两次但只能弹出一次),则会出错。如果用户表示“已完成”并且堆栈中有多个元素,那么也会出现错误。

始终“显示”您的顶部元素,因为这是最后推送的值或结果。

+0

感谢您的帮助。我已经实现了一个堆栈,并且按照我的想法推动它,但出于某种原因2 3 4 *正在做4-(2 * 3)。在检查了它是一个函数还是操作符之后,我将该令牌插入堆栈,但是我是否跳过了某些东西,或者以某种方式错误地执行了它? – Akaraka

+0

@Akaraka - 这听起来像(你没有试图破译你的代码),你正在将操作符(或函数)推入堆栈。有了这个方案,你永远不会推动运营商/功能 - 只有价值。(并且,如另一篇文章所示,您对待操作符和函数完全一样。) –

+0

我查看了我的代码,我不认为我将操作符/函数推入堆栈,因为我检查它是否是一个函数或操作符在推入堆栈之前首先...我可以忽略某处的某个东西吗?谢谢您的帮助! – Akaraka

1

对于像这样的计算器,您应该使用堆栈。每个数字都是一个推动,每个操作都有相应的操作。

st = [] 
while input: 
    if isanumber(input.next()): st.push(input.consume()) 
    else: #its an operator 
    #note this may be wrong for operators that have a specific order 
    if(input.next() == "+"): 
     stack.push(stack.pop() + stack.pop()) 
    # more operations 
    input.consume() 
print(st) 

而这将是粗略的python来做到这一点,在这种情况下,我在做出决定前向前看一个单一的标记。

编辑:

也许应该读你的代码发布前,无论如何你必须推后计算的数字,还试图简化你的代码只有“功能”和“数字”使执行两种功能。正则表达式对于这类事情也很有用,例如http://www.cplusplus.com/reference/std/regex/