javaautomatapostfix-notationprefix-notation

Evaluating Polish Notation in Java with 2 stacks


I am writing an evaluation code for polish notation. When I overcome ClassCastException I get EmptyStack and when I solve Emptystack I get ClassCast I'm in a loop. Here is how I wanted to evaluate the Polish notation:

First I get a string from the user then put it into a stack. For evaluating I use a second stack. Why? Because: An example string: "* + * + 1 2 + 3 4 5 6" First operation here is to add up 3 and 4 but what I'm gonna do with 5 and 6? I put them in another stack. Let's say stack2. I start popping until I found an operator, in this condition I pushed 6 5 4 3 into stack2 and found a plus operator. Then I pop 2 numbers which I pushed to stack2 (the top 2 numbers are 3 and 4), add them up, and push them to stack again. I should evaluate but seems like I am missing a point or this wasn't a good idea at first. Here is my code:

public class Main {

    public static void stack(String srt){  // this function puts the string in srt stack
        String arr[] = srt.split(" "); // I am recognizing if there is a 2 or more digit number
        int size= arr.length;                // with receiving prefix with " " btw every number and operator
        Stack stack= new Stack();
        for (String s : arr) {
           // System.out.println(s);
            stack.push(s);
        }
       // for (int i = 0; i < size; i++) {
       //     System.out.println(stack.pop()); // I checked to see if any 
                                               // problems first now I dont start this
      //  }

          evaluate(stack);             // then calls the evaluate function
    }

    public static void evaluate(Stack stack){
        Stack stack2= new Stack();
        stack2.push(stack.pop());// cuz of there cant be an operator there I pop first 2 number
        stack2.push(stack.pop());
        for (int i = 0; i < (stack.capacity()*2); i++) { // I had a hard time calculating how many times
                                                        // I should cycle through this for and leave it 2 times as stack capacity
            if(stack.peek().toString().equals("*") || stack.peek().toString().equals("-") || stack.peek().toString().equals("/") || stack.peek().toString().equals("+")){
                System.out.println("Checkpoint1");
//                System.out.println(stack2.peek());
                int s2= Integer.parseInt((String) stack2.pop());
                int s1= Integer.parseInt((String) stack2.pop());
                double s3;
                String c = (String) stack.pop();
                switch (c) {
                        case "+":
                            s3=s1+s2;
                            stack2.push(s3);
                        case "-":
                            s3=s1-s2;
                            stack2.push(s3);
                        case "*":
                            s3=s1*s2;
                            stack2.push(s3);
                        case "/":
                            s3=s1/s2;
                            stack2.push(s3);
                    }

            }else{
                System.out.println("Checkpoint 2");
                stack2.push(Integer.parseInt((String) stack.pop()));
//                System.out.println(stack.peek());
            }

            }

//        System.out.println(stack.peek());
//        System.out.println(stack2.peek());
        }



    public static void main(String[] args) {
        String examplestr ="* + * + 1 2 + 3 4 5 6";
        stack(examplestr);
    }
}

Thank you for your help!!!


Solution

  • So turns out the switch-case doesn't operate correctly because I forgot a fundamental part "break". For EmptyStackException, I made a try-catch and put them inside so when it returns empty stack I know evaluation is done and print the result. BUT I still don't know how to deal with these little problems. It feels like I did not solve them properly. Gotta work more. Thanks.

    Edit: I made some more adjustments and this is my final working code. I couldn't detect an error in the results yet.

    Here is the working code;

    import java.util.EmptyStackException;
    import java.util.Stack;
    
    
    public class Main2 {
    
        public static void stack(String srt) {     
            String arr[] = srt.split(" "); 
            int size = arr.length;                
            Stack stack = new Stack();
            for (int i = 0; i < size; i++) {
                if (arr[i].toString().equals("*") || arr[i].toString().equals("-") || arr[i].toString().equals("/") || arr[i].toString().equals("+"))
                    stack.push(arr[i]);
    
                else
                    stack.push(Double.parseDouble(arr[i]));
    
            }
    //        for (int i = 0; i < size; i++) {
    //            System.out.println(stack.pop()); 
    //        }
    
            evaluate(stack);             
        }
    
        public static void evaluate(Stack stack) { 
            Stack stack1 = new Stack();
            stack1.push(stack.pop()); 
            stack1.push(stack.pop()); 
    
            for (int i = 0; i < stack1.capacity(); i++) {  
                try {
                    if (stack.peek().toString().equals("*") || stack.peek().toString().equals("-") || stack.peek().toString().equals("/") || stack.peek().toString().equals("+")) {
    //                    System.out.println("Checkpoint1");
                        double s1 = (double) stack1.pop();
                        double s2 = (double) stack1.pop();
                        double s3;
                        String operator = String.valueOf(stack.pop());
                        switch (operator) {
                            case "+":
                                s3 = s1 + s2;       
                                stack1.push(s3); 
                                break;            
                            case "-":               
                                s3 = s1 - s2;      
                                stack1.push(s3);   
                                break;     
                            case "*":              
                                s3 = s1 * s2;    
                                stack1.push(s3);    
                                break;
                            case "/":
                                s3 = s1 / s2;
                                stack1.push(s3);
                                break;
                        }
    
                    } else {
    //                    System.out.println("Checkpoint 2");
                        stack1.push(Double.parseDouble(String.valueOf(stack.pop())));
    }
    
                } catch (EmptyStackException e) {
                    System.out.println("Notasyonun sonucu: " + stack1.peek());
    
                }
            }
        }
    
        public static void main(String[] args) {
            String notasyon = scanner.nextLine();
            stack(notasyon);
        }
    }