在Java中将Infix转换并计算为Postfix

时间:2014-04-30 14:24:07

标签: java error-handling infix-notation

正如大多数人所知,这类任务令人困惑。经过长时间的搜索编写Java代码来解决这个问题,我收到了以下问题:

Exception in thread "main" java.util.EmptyStackException
    at java.util.Stack.peek(Unknown Source)
    at java.util.Stack.pop(Unknown Source)
    at FirstProTry.parseRPN(FirstProTry.java:128)
    at FirstProTry.main(FirstProTry.java:192)

代码是:

import java.util.*;
import java.io.IOException;
import java.util.Stack;

public class FirstProTry {

    boolean debug;
    final String operands = "^*+-/" ;
    double result;
    private Stack1 theStack;
    private String input;
    private String output = "";

    final static int PRECEDENCE_PLUS=  1;
    final static int PRECEDENCE_MINUS=  1;
    final static int PRECEDENCE_MULTIPLIY=  2;
    final static int PRECEDENCE_DIVIDE=  2;
    final static int PRECEDENCE_EXPONENT=  3;
    final static int PRECEDENCE_PARANTHESIS=  4;

    public FirstProTry(boolean db){
        debug  = db;

    }

    public FirstProTry(String in) {
        input = in;
        int stackSize = input.length();
        theStack = new Stack1(stackSize);
    }

    public String doTrans() {
         for (int j = 0; j < input.length(); j++) {
             char ch = input.charAt(j);
             switch (ch) {
               case '+': 
               case '-':
               gotOper(ch, 1); 
               break; 
               case '*': 
               case '/':
               gotOper(ch, 2); 
               break; 
               case '(': 
               theStack.push(ch);
               break;
               case ')': 
               gotParen(ch); 
               break;
               default: 
               output = output + ch; 
               break;
             }
         }
         while (!theStack.isEmpty()) {
               output = output + theStack.pop();
         }
         //System.out.println(output);
         return output; 
     }

     public void gotOper(char opThis, int prec1) {
              while (!theStack.isEmpty()) {
                 char opTop = theStack.pop();
                 if (opTop == '(') {
                    theStack.push(opTop);
                    break;
                 }
                 else {
                    int prec2;
                    if (opTop == '+' || opTop == '-')
                    prec2 = 1;
                    else
                    prec2 = 2;
                    if (prec2 < prec1) { 
                       theStack.push(opTop);
                       break;
                    }
                    else
                    output = output + opTop;
                 }
              }
              theStack.push(opThis);
     }

     public void gotParen(char ch){ 
          while (!theStack.isEmpty()) {
             char chx = theStack.pop();
             if (chx == '(') 
             break; 
             else
             output = output + chx; 
          }
       }

     //The following is the calculation part

    public void parseRPN(String input){

            String rpnStr = input;
            String[] tokens = rpnStr.split("\\s+");//remove all white space
            //Stack numberStack =new Stack(0);
            Stack<Double> numberStack =new Stack<Double>();

            boolean  bAllowParenthesis = false;
                    for( String token : tokens)
                        {
                        if(token.equals("-")==false && isNumber(token ))
                            {     
                            double d = Double.parseDouble( token  ) ;
                            numberStack.push(d ) ;
                            }
                        else if( isOperand( token , bAllowParenthesis   ) )
                            {
                                if( numberStack.size() <  2 )
                                    {
                                    System.out.println("Invalid Syntax, operator " + token + " must be preceeded by at least two operands");
                                    return;
                                    }
                                    double num1 = numberStack.pop();
                                    double num2 = numberStack.pop() ;
                                    double result = this.calculate( num2 , num1 , token  ) ;
                                    numberStack.push( result);
                            }
                        else if( token.trim().length() > 0 )
                            System.out.println( token + " is invalid, only use numbers or operators " );
                    }
            result= numberStack.pop();

    }

    double getResult() {
        return result;
    }

    public boolean isNumber(String s){
        String  master="-0123456789.";
        s = s.trim();

        for( int i = 0;i < s.length()  ;i++)
            {
            String lttr = s.substring(i, i+1);
            if(master.indexOf( lttr) == -1)
                    return false;
            }
        return true ;       
    }

    public boolean isOperand(String s, boolean allowParanethesis){
        s = s.trim();
        if (s.length() != 1 )
                return false;
        if (allowParanethesis &&  ( s.equals("(") ||  s.equals(")") ) )
                return true;
        else return     operands.indexOf( s ) != -1 ;       
    }

    private Double calculate(double num1, double num2, String op ) {
        if( op.equals("+")) 
                return num1 + num2;
        else if( op.equals("-")) 
                return num1 - num2;
        else if( op.equals("*")) 
            return num1 * num2;
        else if( op.equals("^")) 
            return Math.pow(num1 , num2 );
        else if( op.equals("/") )
            {
                if(num2 ==0 )
                        throw new ArithmeticException("Division by zero!"); 
            return num1 / num2;
            }
        else
            {
            System.out.println(op + " is not a supported operand") ;
            return null;    
             }
    }


    public static void main(String[] args) throws IOException {
        boolean debug = false;  
        FirstProTry rp = new FirstProTry(debug );
        Scanner scan = new Scanner (System.in);
        String output;
        System.out.print("Enter an expression to be evaluated: ");
        String input = scan.next();
        FirstProTry theTrans = new FirstProTry(input);
        output = theTrans.doTrans(); 
        System.out.println("The expression in a postfix form: " + output + '\n');
        String asPostfix_str = output.toString().replaceAll(",", " " ) ;
        rp.parseRPN( asPostfix_str ) ;
        System.out.println("The value of the postfix expression is: " + rp.getResult() ) ;
    }

    class Stack1 {
          private int maxSize;
          private char[] stackArray;
          private int top;
          public Stack1(int max) {
             maxSize = max;
             stackArray = new char[maxSize];
             top = -1;
          }
          public void push(char j) {
             stackArray[++top] = j;
          }
          public char pop() {
             return stackArray[top--];
          }
          public char peek() {
             return stackArray[top];
          }
          public boolean isEmpty() {
             return (top == -1);
         }
     }
}

我尽力解决问题,但我无法解决问题。你能帮助我吗?

1 个答案:

答案 0 :(得分:1)

在这一行中,如果堆栈上没有令牌会发生什么?

result= numberStack.pop();

提示:堆栈是空的,因此没有任何东西可以弹出......

似乎永远不会调用push,所以请在调试循环之前检查为什么会出现这种情况。