为什么说堆栈是空的,即使我把东西放入其中?

时间:2015-11-18 03:23:09

标签: java

由于某些原因,当我调用stack1.empty()或stack1.isEmpty()时,即使我将某些东西推入堆栈,它也会返回true?这是我用来将某些东西推入堆栈的方法......

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

基本上它遍历字符串中的每个字符,并执行我编码的一个案例。在这种情况下,字符是'(',所以我将它推入堆栈。

现在,字符串中的下一个字符是一个字母,因此这种情况称为:

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

该方法运行正常。现在下一部分由于某种原因出错了。字符串中的下一个是*。那么,它应该运行我编码的某个案例,而是运行一个不同的案例....以下是它运行的情况:

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

正如您所看到的,运行此案例的唯一方法是,如果堆栈 为空,但它不是空的!我把东西推入堆栈......我不明白为什么它继续运行这种情况,即使堆栈不是空的。

我希望它改为运行此案例:

     //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");

        }



     }

我的意思是它应该运行案例D,而是运行案例C.为什么要这样做?

编辑:

以下是整个班级:

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

1 个答案:

答案 0 :(得分:4)

&&运算符的优先级高于||,因此在此声明中:

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

以上相当于:

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

更简单的例子:

if (a && b || c)

相当于

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

如果有疑问,请添加parens以明确操作顺序,以便您(以及其他程序员阅读您的代码)明确您的意图。

说明

这对您的整体问题意味着,您的stack1可能为空。在我上面引用的else if中,stack1.empty() && currentChar == '+'都必须是真的。由于情况并非如此,因此下一个术语将进行评估,直到达到currentChar == '*' 为真,因此它会运行案例C.

你的案例D永远不会成立,因为案例C已经检查了相同的字符。案例D将无法联系到。

假设案例C应该表示“stack1为空”和“currentChar是+, - ,*或/”中的一个,那么你需要这样写:

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

但由于您每次都要检查相同的字符,我个人会使用多级if语句:

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

    } else {
    // Case D

    }
}