【问题标题】:Illegal input exception during evaluation of a postfix expression, when my input more than two numbers在评估后缀表达式期间出现非法输入异常,当我输入的数字超过两个时
【发布时间】:2018-03-25 21:13:38
【问题描述】:

我从教科书中得到了大部分代码,而且一切似乎都在工作。例如,如果我有后缀 5 2 + 它会给我 7,这是正确的,但如果我有 5 2 4 * / 7 - 那么它会抛出非法输入异常。当我摆脱非法输入异常时,它可以工作但没有给出正确的答案。

import java.util.*;
import java.util.regex.Pattern;

//Here is my class and main method 


public class postFix {

    public static final Pattern UNSIGNED_DOUBLE = Pattern.compile("((\\d+\\.?\\d*)|(\\.\\d+))([Ee][-+]?\\d+)?.*?");
    public static final Pattern CHARACTER = Pattern.compile("\\S.*?");


      public static Double postfixEvaluate (String expression) {

          Stack<Double> numbers = new Stack<Double>( );   //Stack for numbers
          Stack<Character> operators = new Stack<Character>( );  //Stack for ops

          Scanner input = new Scanner(expression);
          String next;

          while (input.hasNext())            //Iterator is used (hasNext)
          {
              if (input.hasNext(UNSIGNED_DOUBLE))
              {  // if next input is a number
                  next = input.findInLine(UNSIGNED_DOUBLE);
                  numbers.push(new Double(next));  //adding nums to the number stack
              }

              else
                  {  //The next input is an operator

                  next = input.findInLine(CHARACTER);

                  switch (next.charAt(0))
                  {
                      case '+':
                      case '-':
                      case '*':
                      case '/':
                          operators.push(next.charAt(0));  //adding operators to operator stack
                          break;
                      case ')':
                          evaluateStackTops(numbers, operators);
                          break;
                      case '(':
                          break;
                     default:  //Illegal Character
                       throw new IllegalArgumentException("Illegal Character");
                  }
              }
          }

//This what seems to be throwing the exception but I got this right out of the book

        if (numbers.size() != 1)

              throw new IllegalArgumentException("Illegal Input");

          return numbers.pop( );
      }

      public static void evaluateStackTops (Stack<Double> numbers, Stack<Character> operators)
      {
          double operand1 , operand2;

          //check that the stacks have enough items, and get the two operands
          if ((numbers.size()<2)||(operators.isEmpty())) {
              throw new IllegalArgumentException("Illegal Expression");}
              operand2 = numbers.pop();
              operand1 = numbers.pop();

          //carry out an operation based on the operator on top of the stack

         for (int i = 0; i < numbers.size(); i++) {
              switch (operators.pop()) {
                  case '+':
                      numbers.push(operand1 + operand2);
                      break;
                  case '-':
                      numbers.push(operand1 - operand2);
                      break;
                  case '*':
                      numbers.push(operand1 * operand2);
                      break;
                  case '/':
                      numbers.push(operand1 / operand2);
                      break;
                  default:
                      throw new IllegalArgumentException("Illegal Operator");
              }
          }


    public static void main(String[] args) {
        //String expression;
        //Scanner input = new Scanner(expression);

        System.out.println(postFix.postfixEvaluate("(2  3  5  *  /  )" ));

    }
}

【问题讨论】:

  • 如果你把 !=1 改成
  • 不,它似乎没有读取堆栈中的所有数字和运算符。我不知道为什么它不会,除非我错过了什么
  • 您期待什么答案? 5 2 4 * / 7 - 是否代表中缀表达式(5 / (2 * 4)) - 7

标签: java data-structures stack postfix-notation


【解决方案1】:

你的算法有缺陷。它所做的只是构建运算符和操作数的堆栈,然后向后计算表达式。这永远行不通。

我不明白你为什么还要检查括号。后缀表达式中没有括号,因为从中缀到后缀的转换已经去掉了括号。

此外,不需要一堆运算符。后缀的整个想法是,您可以在遇到每个运算符时对其进行评估,并将结果推回堆栈。

基本算法是:

while not end of input
    read next token
    if token is a number
        push on numbers stack
    else if token is operator
        pop value2 and value1 from stack
        result = evaluate value1 <operator> value2
        push result to numbers stack
    else
        invalid input
end while
// at this point, there should be 1 value on numbers stack

所以在评估5 2 4 * / 7 -时,顺序是:

push 5
push 2
push 4
// operator * read here
pop 4
pop 2
evaluate 2 * 4
push 8
// operator / read here
pop 8
pop 5
evaluate 5/8
push 0.625
push 7
// operator - read here
pop 7
pop 0.625
evaluate 0.625 - 7
push -6.375
// end of input here
pop final result

【讨论】:

  • 非常感谢!很有道理。
猜你喜欢
  • 2021-11-07
  • 2019-04-08
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-04
  • 1970-01-01
相关资源
最近更新 更多