TheSuds13
TheSuds13

Reputation: 347

Why is it saying stack is empty even though I push something into it?

For some reason when I call the stack1.empty() or stack1.isEmpty(), it returns true even though I pushed something into the stack? Here is the method I use to push something into the stack...

//Case B:
     else if(currentChar == '('){
         Character charObj = Character.valueOf('(');
         stack1.push(charObj);
         System.out.println("Case B");
     }

Basically it iterates through each character in a string, and does one of the cases that I coded. In this case, the character is a '(', so I have it pushed into the stack.

Now, the next character in the string is a letter, so this case is called:

//Case A:
     if(currentChar != '+' && currentChar != '-' && currentChar != '*' && currentChar != '/' && currentChar != '(' && currentChar != ')' ){
         postfixString += currentChar;
         System.out.println("Case A");
     }

That method works fine. Now the next part goes wrong for some reason. The next thing in the string is a *. SO, it's supposed to run a certain case that I coded, but instead it runs a different case....Here is the case that it runs:

//Case C:
     else if(stack1.empty() && currentChar == '+' || currentChar == '-' || currentChar == '*' || currentChar == '/'){
         stack1.push(currentChar);
         System.out.println("Case C");
     }

As you can see, the only way to run this case is if the stack is empty, but it's not empty! I pushed something into the stack... I don't understand why it keeps running this case even though the stack is not empty.

I want it to run this case instead:

     //Case D: If character is an operator, it goes into a loop checking if topstack is higher precedence to the current character
     // If it is, the stack pops onto the end of the postfix string. If it isn't, the stack pushes the current scanned character.
     // It then breaks out of the loop
     else if(currentChar == '+' || currentChar == '-' || currentChar == '*' || currentChar == '/' && !stack1.isEmpty()){
         char topStack = stack1.peek();

        while(!stack1.isEmpty()){
            if(precedence(topStack, currentChar)){
                postfixString += stack1.pop();
            }
            else{
                stack1.push(currentChar);
                break;
            }

            System.out.println("Case D");

        }



     }

I mean it should run case D, but instead it runs case C. Why is it doing this?

EDIT:

Here's the entire class:

import java.util.Stack;

public class InfixToPostfixConverter
{
//**********************************************************************
//The precedence method determines the precedence between two operators.
//If the first operator is of higher or equal precedence than the second
//operator, it returns the value true, otherwise it returns false.
//***********************************************************************
   public static boolean precedence(char topStack, char currentChar)
   {
   if(topStack == currentChar){
       return true;
   }

   // If topStack is division or multiplication, it will always have precedence no matter what
   if(topStack == '/' || topStack == '*'){
       return true;
   }
   // If topStack is addition or subtraction...
   else if(topStack == '+' || topStack == '-'){
       if(currentChar == '+' || currentChar == '-'){
           return true;
       }
       else if(currentChar == '*' || currentChar == '/'){
           return false;
       }
   }

   return false;
   }

//*************************************************************************
//The static convertToPostfix method will convert the infixString
//into the corresponding postfix string. Check the algorithm on
//assignment #11's description page. Mark each case clearly inside the code
//*************************************************************************
   public static String convertToPostfix(String infixString)
   {
  //initialize the resulting postfix string
  String postfixString = "";

  //initialize the stack
  Stack<Character> stack1 = new Stack<Character>();

 //Obtain the character at index i in the string
  for (int i=0; i < infixString.length(); i++)
  {
     char currentChar = infixString.charAt(i);

    //Case A:
     if(currentChar != '+' && currentChar != '-' && currentChar != '*' && currentChar != '/' && currentChar != '(' && currentChar != ')' ){
         postfixString += currentChar;
         System.out.println("Case A");
     }

    //Case B:
     else if(currentChar == '('){
         stack1.push(currentChar);
         System.out.println("Case B");
     }

     else if(currentChar == '+' || currentChar == '-' || currentChar == '*' || currentChar == '/'){
         //Case C
         if(stack1.isEmpty()){
             stack1.push(currentChar);
             System.out.println("Case C");
         }
         //Case D
         else{
             char topStack = stack1.peek();

             while(!stack1.isEmpty()){
                if(precedence(topStack, currentChar)){
                    postfixString += stack1.pop();
                }
                else{
                    stack1.push(currentChar);
                    break;
                }

                System.out.println("Case D");

            }
         }
     }
    //Case E:
     else if(currentChar == ')' && !stack1.isEmpty()){
         while(!stack1.isEmpty() && stack1.peek() != '('){
             postfixString += stack1.pop();
             System.out.println("Case E");
         }
         if(!stack1.isEmpty() && stack1.peek() == '('){
             stack1.pop();
         }
     }


  } //end of for loop


    //Case F:
  if(!stack1.isEmpty() && stack1.peek() == '('){
      return "No matching close parenthesis error.";
  }
  else if(!stack1.isEmpty() && stack1.peek() != '('){
      while(!stack1.isEmpty() && stack1.peek() != '('){
          postfixString += stack1.pop();
      }
  }

  System.out.println("Case F");
  return postfixString;


}//end of convertToPostfix method

}//end of the InfixToPostfixConverter class

Upvotes: 1

Views: 319

Answers (1)

type_outcast
type_outcast

Reputation: 635

The && operator has a higher precedence than ||, so in this statement:

else if(stack1.empty() && currentChar == '+' || currentChar == '-' || currentChar == '*' || currentChar == '/'){

The above is equivalent to:

else if( ( stack1.empty() && currentChar == '+' ) || currentChar == '-' || currentChar == '*' || currentChar == '/'){

For a simpler example:

if (a && b || c)

is equivalent to

if ( (a && b) || c )

When in doubt, add parens to make the order of operations explicit so that you (and other programmers reading your code) are clear on your intention.

Explanation

What this means for your overall question is, your stack1 is probably not empty. In the else if I've quoted above, stack1.empty() && currentChar == '+' would both have to be true. Since that isn't the case, the next terms are evaluated until it gets to currentChar == '*', which is true, so it runs Case C.

Your Case D will never be true, because Case C already checks the same characters. Case D will not be reached.

Assuming Case C is supposed to mean both "stack1 is empty" AND "currentChar is one of +, -, *, or /", then you would need to write it as such:

else if (stack1.empty() && (currentChar == '+' || ...)) {

But since you are checking for the same characters every time, I would personally use a multi-level if statement:

else if (currentChar == '+' || currentChar == '-' || ...) {
    if (stack1.empty()) {
    // Case C

    } else {
    // Case D

    }
}

Upvotes: 4

Related Questions