0

嘿伙计们,我正在编写一个程序来使用堆栈将中缀表达式转换为后缀表达式,其中输入是从用户那里读取的。问题是堆栈为空的情况下,我在一段调用 peek() 的代码上不断收到空指针异常。令人困惑的是,我有一个 if 语句应该通过调用 isEmpty() 来防止这种情况发生。有任何想法吗?具体来说,输入“A+BC”给我带来了问题,尽管“(A+BC)”工作得很好

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

1 回答 1

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。

请注意,仅在进入循环之前if检查您在第二个左右的时间。它不会在任何后续迭代中进行检查,因此不会阻止我上面描述的场景。while

于 2013-04-19T05:11:48.060 回答