使用堆栈的JAVA反向波兰表示法

时间:2017-10-30 14:31:34

标签: java data-structures stack

我使用Stacks编写了基于维基百科RPN算法的代码:

public static void reversePolish(String[] x){
        Stack temp = new Stack();
        Integer one;
        Integer two;
        Integer result;
        for(String x1:x){
            switch(x1){
                case "+":
                    one = (Integer) temp.pop();
                    two = (Integer) temp.pop();
                    result = one+two;
                    System.out.println(one + "+"+two);
                    temp.push(result);
                    break;
                case "-":
                    one = (Integer) temp.pop();
                    two = (Integer) temp.pop();
                    result = one+two;
                    temp.push(result);
                    break;
                default :
                    temp.push(Integer.parseInt(x1));
                }
        }
        result = (Integer) temp.pop();
        System.out.println(result);
    }

然而它给了我一个错误:

Exception in thread "main" java.util.EmptyStackException
    at java.util.Stack.peek(Stack.java:102)
    at java.util.Stack.pop(Stack.java:84)
    at TestingItOut.reversePolish(TestingItOut.java:57)
    at TestingItOut.main(TestingItOut.java:31)
C:\Users\Sanchit\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)

我完全不知道是什么引起了这个错误。需要帮助

2 个答案:

答案 0 :(得分:1)

我不认为抛出EmptyStackException是您程序的问题 - 它在我的计算机上运行得非常好。

引发EmptyStackException的原因可能是您传递给reversePolish()的数据。

例如,有效输入应为:

"1", "2", "+", "3", "-", "6", "+"

这意味着1+2-3+6。也就是说,如果您希望使用二元运算符和2个操作数计算结果,请先写入操作数并将运算符放在它们之后。

有关详细信息,请参阅Reverse Polish Notation

那么为什么抛出EmptyStackException

您的算法很简单:在操作数上,将其推入堆栈,在操作符上,弹出操作数,计算结果并将其推回。问题是,如果程序找到一个运算符并且堆栈中没有足够的操作数,它仍会尝试弹出2个必需的操作数,并EmptyStackException

要优化算法,您可以在弹出之前首先检查堆栈的大小,并打印一条人类可读的消息,说“没有足够的操作数!”而不是抛出EmptyStackException。代码可以是这样的:(部分)

case "+":
if (temp.size() < 2) {
    System.out.println("There's not enough operands!");
    return;
}
one = (Integer) temp.pop();
two = (Integer) temp.pop();
result = one + two;
System.out.println(one + " + " + two);
temp.push(result);
break;

更多。

如果你没有注意到,你已在result = one + two;下写了case "-":,我将其视为一个简单的拼写错误。它应该是result = one - two

如果在等于或高于Java 1.5的环境中运行程序,Stack应包含泛型类型。在您的情况下,它应该是Stack<Integer> temp = new Stack<Integer>();。 (如果您使用的是Java 7或更高版本,则可以为了简单起见而编写Stack<Integer> temp = new Stack<>();,然后您不必编写one = (Integer) temp.pop();one = temp.pop()没问题。

还有一件事:

你只需在最后写result = (Integer) temp.pop();,这仍然不是完美的事情。

将输入成像为"1", "2", "+", "3", "-", "6", "+", "7"

翻译,它是1 + 2 - 3 + 6 7。如果你把它写下来并交给你的老师,你会得到一个零标记,因为没有操作员连接67 - 也就是说,7是多余的。

但是,如果您将此项提交给您的计划,它将输出7而不是发出一些警告。这不是理想的行为。

所以,正确的做法是写:

if (temp.size() == 1) {
    result = (Integer) temp.pop();
    System.out.println(result);
} else System.out.println("Redundant operands!");

答案 1 :(得分:0)

休息一下;命令和所有它似乎工作。现在不要太乱用了!