【问题标题】:Prefix expression to evaluate multiple expressions simultaneously前缀表达式同时计算多个表达式
【发布时间】:2015-04-13 07:29:46
【问题描述】:
private class InputListener implements ActionListener
    {
      public void actionPerformed(ActionEvent e)
      {
         Stack<Integer> operandStack = new Stack<Integer>();
         Stack<Character> operatorStack = new Stack<Character>();

         String input = inputTextField.getText();

         StringTokenizer strToken = new StringTokenizer(input, " ", false);


         while (strToken.hasMoreTokens())
         {
             String i = strToken.nextToken();
             int operand;
             char operator;

             try
             {
                 operand = Integer.parseInt(i);
                 operandStack.push(operand);
             }
             catch (NumberFormatException nfe)
             {
                 operator = i.charAt(0);
                 operatorStack.push(operator);
             }
          }
          int result = sum (operandStack, operatorStack);
          resultTextField.setText(Integer.toString(result));
       }

我的前缀表达式代码一次只会计算一个表达式(即 + 3 1)。我希望它在一个用户输入表达式中评估多个表达式(即 * + 16 4 + 3 1)。如何编辑提供的代码以使其评估多个表达式?感谢您的帮助。

【问题讨论】:

  • 方法sum在做什么?
  • @isnot2bad sum 方法计算操作数的总和或乘积。我在 sum 方法中使用 if...else if 语句来计算。例如: if(operator == '+'){operand1 =operandStack.pop();操作数 2 = 操作数堆栈.pop();结果 = 操作数 2 + 操作数 1; }。如何编辑代码以使其一次评估多个表达式?

标签: java expression


【解决方案1】:

为了简单地让你的程序做更多的事情,你可以使用一个循环来继续对operandStack 进行操作,并将前一个结果的结果推入堆栈。我留下了我的println 声明,这样你就可以看到它在做什么。我还修改了您的方法,使其可以位于独立的 main 方法中。

你应该研究一下Shunting-yard 算法,它实现起来很有趣,而且有点像你在这里所做的。 http://en.wikipedia.org/wiki/Shunting-yard_algorithm

public static void main(String[] args) {
    Stack<Integer> operandStack = new Stack<Integer>();
    Stack<Character> operatorStack = new Stack<Character>();

    String input = "12 + 13 - 4";

    StringTokenizer strToken = new StringTokenizer(input, " ", false);

    while (strToken.hasMoreTokens()) {
        String i = strToken.nextToken();
        int operand;
        char operator;

        try {
            operand = Integer.parseInt(i);
            operandStack.push(operand);
        } catch (NumberFormatException nfe) {
            operator = i.charAt(0);
            operatorStack.push(operator);
        }
    }

    // loop until there is only 1 item left in the operandStack, this 1 item left is the result
    while(operandStack.size() > 1) {
        // some debugging println
        System.out.println("Operate\n\tbefore");
        System.out.println("\t"+operandStack);
        System.out.println("\t"+operatorStack);

        // perform the operations on the stack and push the result back onto the operandStack
        operandStack.push(operate(operandStack, operatorStack));

        System.out.println("\tafter");
        System.out.println("\t"+operandStack);
        System.out.println("\t"+operatorStack);
    }

    System.out.println("Result is: " + operandStack.peek());
}

/**
 * Performs math operations and returns the result. Pops 2 items off the operandStack and 1 off the operator stack. 
 * @param operandStack
 * @param operatorStack
 * @return
 */
private static int operate(Stack<Integer> operandStack, Stack<Character> operatorStack) {
    char op = operatorStack.pop();
    Integer a = operandStack.pop();
    Integer b = operandStack.pop();
    switch(op) {
        case '-':
            return b - a;
        case '+':
            return a + b;
        default:
            throw new IllegalStateException("Unknown operator '"+op+"'");
    }
}

我让operate 方法(以前称为sum)尽可能地接近你所拥有的,但是我认为你的代码可以通过简单地传递2个整数和一个运算符来改进。让函数改变你的堆栈并不是一件好事,而且可能会导致令人困惑的问题。

考虑将您的方法签名改为:

private static int operate(Integer a, Integer b, char operator) {
    switch(operator) {
        case '-':
            return b - a;
        case '+':
            return a + b;
        default:
            throw new IllegalStateException("Unknown operator '"+operator+"'");
    }
}

然后从堆栈中弹出并将它们传递给方法。将您的堆栈更改代码保存在一个地方。

operandStack.push(operate(operandStack.pop(), operandStack.pop(), operatorStack.pop()));

【讨论】:

  • 谢谢 ug_。我现在正在实现你的代码,但不确定将你给我的最后一行代码放在哪里:operandStack.push(operate(operandStack.pop(),operandStack.pop(),operatorStack.pop()));。我在哪里实现它?
  • @Jeremy 它将在 while 循环中代替 operandStack.push(operate(operandStack, operatorStack));
  • 我还需要使用 resultTextField.setText();将结果存储在 GUI 中的语句,但您删除了它。我现在如何使用它?
  • @Jeremy 将它重新添加到...与以前一样。
  • 我重新添加了它,它通过将 'result' 替换为 'operandStack.peek()' 来工作,但现在还有另一个问题;使用多个运算符无法正确计算。前缀表达式 * + 16 4 + 3 1 应该等于 80,但它是 128。我该如何纠正这个问题?
猜你喜欢
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
相关资源
最近更新 更多