微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Infix to Postfix 表达式中的关联规则

如何解决Infix to Postfix 表达式中的关联规则

我使用 infixpostfixstack 算法:

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 举报,一经查实,本站将立刻删除。