首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

中綴表達式轉後綴表達式(逆波蘭表示法)詳細步驟圖解

     編輯:C 語言問答

核心算法:Shunting Yard Algorithm (調度場算法)

由 Dijkstra 提出,使用**運算符棧**將中綴轉後綴。核心規則:

  1. 操作數直接輸出
  2. 左括號入棧
  3. 右括號:彈出運算符直到遇到左括號
  4. 運算符:若優先級大於棧頂則入棧,否則彈出棧頂輸出直到滿足條件再入棧
  5. 掃描結束:彈出剩餘運算符

運算符優先級與結合性

優先級運算符結合性
1 (最高)() [] -> .左到右
2! ~ ++ -- +(一元) -(一元) *(間接) &(取址) sizeof右到左
3* / %左到右
4+ -左到右
.........

題目詳解

(1) -A+B-C+D → A B - C - D + (即 A-B+C-D+)

逐步演示:

步驟輸入動作輸出運算符棧
1- (一元負號)入棧-
2A輸出操作數A-
3+一元-優先級>+,彈出-輸出,+入棧A -+
4B輸出操作數A - B+
5-+與-同級左結合,彈出+輸出,-入棧A - B +-
6C輸出操作數A - B + C-
7+-與+同級,彈出-輸出,+入棧A - B + C -+
8D輸出操作數A - B + C - D+
9結束彈出剩餘+A - B + C - D +

(2) A*-B+C → A B - * C + (即 AB-*C+)

步驟輸入動作輸出運算符棧
1A輸出A
2*入棧A*
3- (一元)一元-優先級>*,入棧A*, -
4B輸出A B*, -
5+彈出一元-輸出,彈出*輸出,+入棧A B - *+
6C輸出A B - * C+
7結束彈出+A B - * C +

C語言實現:中綴轉後綴

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX 100

int precedence(char op) {
    if (op == '+' || op == '-') return 1;
    if (op == '*' || op == '/' || op == '%') return 2;
    if (op == '^') return 3;  // 次方,右結合
    return 0;
}

int is_operator(char c) {
    return c=='+'||c=='-'||c=='*'||c=='/'||c=='%'||c=='^';
}

void infix_to_postfix(const char* infix, char* postfix) {
    char stack[MAX];
    int top = -1;
    int j = 0;
    
    for (int i = 0; infix[i]; i++) {
        char c = infix[i];
        if (isspace(c)) continue;
        
        if (isalnum(c)) {  // 操作數
            postfix[j++] = c;
        } else if (c == '(') {
            stack[++top] = c;
        } else if (c == ')') {
            while (top >= 0 && stack[top] != '(') {
                postfix[j++] = stack[top--];
            }
            if (top >= 0) top--;  // 彈出左括號
        } else if (is_operator(c)) {
            // 處理一元運算符簡化:假設表達式已預處理或用特殊標記
            while (top >= 0 && stack[top] != '(' && 
                   precedence(stack[top]) >= precedence(c)) {
                postfix[j++] = stack[top--];
            }
            stack[++top] = c;
        }
    }
    
    while (top >= 0) {
        postfix[j++] = stack[top--];
    }
    postfix[j] = '\0';
}

int main() {
    char infix[MAX], postfix[MAX];
    printf("輸入中綴表達式: ");
    fgets(infix, MAX, stdin);
    infix[strcspn(infix, "\n")] = '\0';
    
    infix_to_postfix(infix, postfix);
    printf("後綴表達式: %s\n", postfix);
    return 0;
}

後綴表達式求值(驗證轉換正確性)

int eval_postfix(const char* postfix) {
    int stack[MAX];
    int top = -1;
    
    for (int i = 0; postfix[i]; i++) {
        char c = postfix[i];
        if (isdigit(c)) {
            stack[++top] = c - '0';
        } else if (is_operator(c)) {
            int b = stack[top--];
            int a = stack[top--];
            int res = 0;
            switch(c) {
                case '+': res = a + b; break;
                case '-': res = a - b; break;
                case '*': res = a * b; break;
                case '/': res = a / b; break;
            }
            stack[++top] = res;
        }
    }
    return stack[top];
}

常見錯誤與調試

  • 忽略一元運算符處理 (如 -A vs A-B)
  • 運算符優先級比較邏輯錯誤 (>= vs > 影響結合性)
  • 括號匹配檢查缺失
  • 多位數操作數解析 (需掃描完整數字)
  • 空格處理遺漏

擴展應用

  • 編譯器前端:語法分析、中間代碼生成
  • 計算器程序:動態表達式求值
  • 腳本引擎:運行時表達式解析
  • 數據庫查詢優化:條件表達式重寫
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved