如何解决Infix to Postfix 表达式中的关联规则
我使用 infix
的 postfix
到 stack
算法:
static int Prec(char ch) {
switch (ch) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
static String infixToPostfix(String exp) {
String result = new String("");
Stack<Character> stack = new Stack<>();
for (int i = 0; i < exp.length(); ++i) {
char c = exp.charat(i);
if (Character.isLetterOrDigit(c))
result += c;
else if (c == '(')
stack.push(c);
else if (c == ')') {
while (!stack.isEmpty() && stack.peek() != '(')
result += stack.pop();
stack.pop();
} else {
while (!stack.isEmpty() && Prec(c) <= Prec(stack.peek())) {
result += stack.pop();
}
stack.push(c);
}
}
while (!stack.isEmpty()) {
if (stack.peek() == '(')
return "Invalid Expression";
result += stack.pop();
}
return result;
}
输入: K+L-M*N+(O^P)*W/U/V*T+Q^J^A
预期输出: KL+MN*-OP^W*U/V/T*+QJA^^+
实际输出: KL+MN*-OP^W*U/V/T*+QJ^A^+
如果当前运算符和栈顶运算符的优先级为 same
,则检查它们的结合性,
- 如果运算符的结合性是从右到左,则只需将
push
运算符放入堆栈。 - 如果运算符的结合性是从左到右,那么
pop
运算符来自堆栈并再次检查当前运算符和堆栈顶部运算符的结合性。
预期输出和实际输出的差异在于子表达式 ^J^A
的计算时间。
当到达字符 Q
时,堆栈包含 ['+']
。我输出操作数 Q
并移动到表达式中的下一个字符。对于上述规则,应该发生以下情况:
-
^
是Q
之后的下一个字符。由于^
的优先级高于+
,因此我将其压入堆栈['+','^']
并将指针移至J
。 - 输出
J
作为操作数并移动指针。 - 指针现在位于
^
。由于栈顶也包含一个^
,它们具有相同的优先级,因此我们需要检查从右到左的关联规则。因此,我们将^
压入堆栈。所以堆栈看起来像['+','^','^']
。 - 指针现在位于最后一个字符
A
处,所以只需输出它。 - 既然我们已经到了表达式的末尾,我们可以开始从堆栈中弹出运算符,这样子表达式的后缀形式将类似于
QJA^^+
。
但是,我的代码不适用于关联性。有人能解释一下如何在上述实现中处理关联性吗?
解决方法
这是一个简单的修复。您需要更新 while
循环条件:
while (!stack.isEmpty() && Prec(c) <= Prec(stack.peek()))
致:
while (!stack.isEmpty() && (prec(c) < prec(stack.peek()) || (prec(c) == prec(stack.peek()) && isLeftToRightAssociative(stack.peek()))))
这里是方法isLeftToRightAssociative()
:
public static boolean isLeftToRightAssociative(Character operator)
{
//You can also use return operator != '^' as an alternative to the if-else given below
if (operator == '^') return false;
else return true;
}
我应该补充一点,如果用户输入包含 unary operators
的表达式,您的代码将不会产生正确的输出。如果您将使用 unary operators
,您应该更新您的代码。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。