簡體   English   中英

中綴到后綴表達式中的關聯性規則

[英]Associativity rule in Infix to Postfix expression

我使用stackpostfix算法的中infix

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+LM*N+(O^P)*W/U/V*T+Q^J^A

預期 Output: KL+MN*-OP^W*U/V/T*+QJA^^+

實際Output: KL+MN*-OP^W*U/V/T*+QJ^A^+

如果當前運算符和堆棧頂部的運算符具有same的優先級,則檢查它們的關聯性,

  • 如果運算符的關聯性是Right to Left ,則只需push運算符壓入堆棧。
  • 如果運算符的關聯性是Left to Right ,則從堆棧中pop運算符並再次檢查當前運算符和堆棧頂部運算符的關聯性。

預期和實際 output 的差異在於評估子表達式^J^A的時間。 當到達字符Q時,堆棧包含['+'] 我 output 操作數Q並移動到表達式中的下一個字符。 關於上述規則,應該發生以下情況:

  • ^Q之后的下一個字符。 由於^的優先級高於+ ,因此我將其推入堆棧['+','^']並將指針移至J
  • Output J因為它是一個操作數和移動指針。
  • 指針現在位於^ 由於棧頂也包含一個^ ,它們具有相同的優先級,所以我們需要檢查從右到左的關聯規則。 因此,我們將^壓入堆棧。 所以堆棧看起來像['+','^','^']
  • 指針現在在最后一個字符A所以只是 output 它。
  • 由於我們已經到達表達式的末尾,我們可以開始從堆棧中彈出運算符,因此子表達式的后綴形式將看起來像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的表達式,您的代碼將不會產生正確的 output 。 如果您將使用unary operators ,您應該更新您的代碼。

輕松修復 - 就在 else 語句之前添加另一個 else if

else if (c==stack.peek() and c=='^')
{ stack.push(c); }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM