public class ShuntingYard
{
public String infix2postfix(String infix)
{
Stack<String> s = new Stack<String>();
String[] tokens = infix.split(" ");
StringBuilder output = new StringBuilder();
Integer plus = Integer.getInteger("+", 1);
Integer minus =Integer.getInteger("-", 1);
Integer multiply = Integer.getInteger("*", 2);
Integer divide = Integer.getInteger("/", 2);
Integer exponent = Integer.getInteger("^", 3);
for (int i = 0; i < tokens.length; i++)
{
if (tokens[i].matches("[0-9]"))
{
output.append(tokens[i] + " ");
}
else if (tokens[i].equals("+") || tokens[i].equals("-") || tokens[i].equals("*") || tokens[i].equals("/")
|| tokens[i].equals("^"))
{
int a = plus.intValue();
int b = minus.intValue();
int c = multiply.intValue();
int d = divide.intValue();
int e = exponent.intValue();
if (s.isEmpty() == false && tokens[i].valueOf(a).compareTo(s.peek()) >= 0||
s.isEmpty() == false && tokens[i].valueOf(b).compareTo(s.peek()) >= 0 ||
s.isEmpty() == false && tokens[i].valueOf(c).compareTo(s.peek()) >= 0 ||
s.isEmpty() == false && tokens[i].valueOf(d).compareTo(s.peek()) >= 0 ||
s.isEmpty() == false && tokens[i].valueOf(e).compareTo(s.peek()) >= 0)
{
output.append(s.peek() + " ");
s.pop();
}
s.push(tokens[i]);
}
else if (tokens[i].equals("("))
{
s.push(tokens[i]);
}
else if(tokens[i].equals(")"))
{
while (!(s.peek().equals("(")))
{
output.append(s.pop());
}
if (s.isEmpty() == true)
{
System.out.println("Error: mismatching parentheses");
}
s.pop();
}
}
for (int i = 0; s.isEmpty() == false; i++)
{
if(s.peek().equals("(") || s.peek().equals(")"))
{
System.out.println("Error: mismatching parentheses");
}
output.append(s.pop());
}
return output.toString();
}
}
@Test
public void infix2postfixTest()
{
assertEquals("3 4 5 6 - 7 * 8 / + - 9 *", s.infix2postfix("3 * ( 4 + ( 5 - 6 ) * 7 / 8 ) - 9"));
}
当我运行ShuntingYard测试时,发布了第二个代码,我得到一个指向此行的EmptyStackException
:
while (!(s.peek().equals("(")))
但逻辑对我有意义,我说如果令牌是&#34;)&#34;,那么虽然堆栈顶部不是&#39; ta&#34;(& #34;将堆栈的顶部附加到输出并将其从堆栈中删除。我在这里遗漏了什么吗?
这是我的堆栈偷看方法:
public T peek()
{
if (isEmpty() == true)
{
throw new java.util.EmptyStackException();
}
return stack.get(stack.size()-1);
}
答案 0 :(得分:0)
你一直弹出并偷看Stack
而不先检查它是否为空。偷看或弹出空堆栈会生成您获得的EmptyStackException
。正如您所指出的那样,Stack
类会检查isEmpty()
中的peek()
,但它只会生成EmptyStackException
。作为peek()
的来电者,您有责任先自己检查isEmpty()
!如果你不这样做,那么你已经为Stack
创造了一个不可能的情况 - 如果没有任何东西可以从空{{1}中偷看,它就无法向你展示一个偷看的结果。 }!
你应该替换:
Stack
类似于:
else if(tokens[i].equals(")"))
{
while (!(s.peek().equals("(")))
{
output.append(s.pop());
}
if (s.isEmpty() == true)
{
System.out.println("Error: mismatching parentheses");
}
s.pop();
}
修复程序的实现方式可能与我的示例不同。但是要说的是,在致电else if(tokens[i].equals(")"))
{
while(!s.isEmpty())
{
if(s.peek().equals("("))
{
s.pop();
if(s.isEmpty())//we just popped so the while check no longer applies
{
System.out.println("Error: mismatching parentheses");
}
}
else
{
output.append(s.pop());
}
}
}
或isEmpty()
之前,您必须先检查peek()
。
作为补充说明,我想指出用于打印不匹配括号错误的原始代码无法访问。 if语句结束后执行if语句,当while语句结束时,保证s pop()
非空!该保证使后续的pop调用安全,但也意味着永远不会执行错误消息。我修复了我的示例中的其他错误,但我想更详细地解释它,否则您可能不会注意到。