1

到目前为止,这是我的代码:

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 * -'?任何帮助,将不胜感激。提前致谢!

4

2 回答 2

1

是的,一堆。并且可以使用数组和计数器轻松实现简单的堆栈——无需使用花哨的类。

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

推送是更新 A[i] 并增加 i。Pop 是减量 i 和参考 A[i]。“8 9 +”是push(8),push(9),弹出前两个元素,相加,push结果。请注意,运算符永远不会被推送,只有操作数/结果。

'2 3 4 * -' 将是 push(2), push(3), push(4), pop top two, multiply, push result, pop two, minus, push result。

"7 6 + cos" 将是 push(7), push(6), pop 二, add, push result, pop one, 执行 "cos", push result。

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

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

于 2012-10-16T02:57:26.970 回答
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)

那将是粗暴的蟒蛇,在这种情况下,我会在做出决定之前先看一个标记。

编辑:

可能应该在发布之前阅读您的代码,无论如何您必须始终推回计算出的数字,还尝试将您的代码简化为只有“函数”和“数字”才能执行两者的函数。正则表达式对这类事情也很有用,例如http://www.cplusplus.com/reference/std/regex/

于 2012-10-16T02:41:07.257 回答