2013-04-19 2 views
0

Привет, ребята, я пишу программу для преобразования выражений infix в постфиксные, используя стеки, где ввод считывается от пользователя. Проблема заключается в случаях, когда стек пуст. Я продолжаю получать исключения nullpointer в разделе кода, который вызывает peek(). Смешно, что у меня есть оператор if, который должен защитить это от использования с помощью вызова isEmpty(). Есть идеи? В частности, вход "A + BC" это то, что дает мне проблемы, хотя "(A + BC)" отлично работаетNullPointerException в реализации стека ArrayDeque

import java.util.*; 
/** 
* 
* @author Adam 
*/ 
public class PostfixConversion 
{ 
    static Deque<Character> stack = new ArrayDeque<>(); 

    public static boolean precedence(char first, char second) 
    { 
     if(first == '+' || first == '-') 
      return false; 
     else if(first == '*' || first == '/') 
     { 
      if(second == '*' || second == '/') 
       return false; 
      else 
       return true; 
     } 
     else 
      return false; 
    } 

    public static String convertToPostfix(String infixExp) 
    { 
     int leftCount = 0; 
     int rightCount = 0; 
     Character item; 

     String rightError = "There is no matching left parenthesis."; 
     String leftError = "There is no matching right parenthesis."; 
     String postFix = ""; 

     if(infixExp.indexOf(")") < infixExp.indexOf("(")) 
      return rightError; 
     if(infixExp.lastIndexOf(")") < infixExp.lastIndexOf("(")) 
      return leftError; 

     for(int i = 0; i < infixExp.length(); i++) 
     { 
      if(Character.isLetter(infixExp.charAt(i))) 
       postFix += infixExp.charAt(i); 

      if(infixExp.charAt(i) == '(') 
      { 
       item = infixExp.charAt(i); 
       stack.push(item); 
       leftCount++; 
      } 

      if(infixExp.charAt(i) == ')') 
      { 
       while(stack.peek() != '(') 
        postFix += stack.pop().charValue(); 
       stack.pop(); 
       rightCount++; 
      } 

      if(infixExp.charAt(i) == '+' || 
       infixExp.charAt(i) == '-' || 
       infixExp.charAt(i) == '*' || 
        infixExp.charAt(i) == '/') 
      { 
       if(stack.isEmpty() == false) 
       { 
        while(PostfixConversion.precedence(infixExp.charAt(i), stack.peek().charValue()) == false) 
        { 
         if(stack.peek().charValue() == '(') 
          break; 
         postFix += stack.pop().charValue(); 
        } 
       } 

       item = infixExp.charAt(i); 
       stack.push(item); 
      } 
     } 

     if(leftCount > rightCount) 
      return leftError; 
     if(rightCount > leftCount) 
      return rightError; 

     return postFix; 
    } 
} 
+0

Произошла ошибка в методе преобразования, в котором метод приоритета вызывается для сравнения операторов (+, -, *, /), условия цикла while. –

ответ

0

В следующем цикле:

 while(stack.peek() != '(') 
      postFix += stack.pop().charValue(); 

вы не проверить был ли стек пустым.

То же самое для следующего цикла:

  while(PostfixConversion.precedence(infixExp.charAt(i), stack.peek().charValue()) == false) 
      { 
       if(stack.peek().charValue() == '(') 
        break; 
       postFix += stack.pop().charValue(); 
      } 

После того, как стек пошел пустым, peek() вернется null и вы получите NPE от autounboxing.

Обратите внимание, что у вас есть if вокруг второго while проверяется только перед тем в цикл. Он не проверяется ни на какие последующие итерации, поэтому не будет препятствовать описанному выше сценарию.

+0

Ну, я получаю ошибку с вводом «A + B-C», так что конкретный цикл while, на который вы указываете, не должен быть достигнут правильно? Что касается второго: –

+0

'if (stack.isEmpty() == false) { while (PostfixConversion.precedence (infixExp.charAt (i), stack.peek(). CharValue()) false) {. , если (stack.peek() charValue() == '(') перерыва; Postfix + = stack.pop() charValue(); .}} ' –

+0

@AdamChmurzynski: Параметр' if' является * before * the loop. Он не проверяется снова после первой итерации. – NPE

Смежные вопросы