Question

As most of you know, this type of task is confusing. After a long journey of searching to write a Java code to solve this problem, I received the following problem:

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)

The code is:

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);
         }
     }
}

I did all my best to solve the problem but I couldn't. Can you guys help me out?

Was it helpful?

Solution

In this line what happens if there are no tokens on the stack?

result= numberStack.pop();

Hint: the stack is empty so there is nothing to pop...

It seems as if push is never called, so please debug the loop before to check why this is the case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top