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

C語言實現三數四則運算表達式求值:運算符優先級解析與棧式算法

     編輯:程式設計綜合問答

問題本質

輸入形如3+5*2的表達式,僅用printf/scanf/switch/if實現正確運算,核心難點在於運算符優先級處理(乘除先於加減)。

核心思路:雙棧法(運算符棧+操作數棧)

這是編譯原理中經典的表達式求值算法,邏輯清晰且可擴展:

算法流程

  1. 掃描輸入字符,數字入操作數棧
  2. 遇到運算符,比較其與運算符棧頂優先級:
    • 優先級高於棧頂 → 直接入棧
    • 優先級低於或等於棧頂 → 棧頂運算符出棧,彈出兩個操作數計算,結果入操作數棧,重新比較
  3. 掃描結束,依次處理剩餘運算符
  4. 操作數棧頂元素即為最終結果

優先級定義

int precedence(char op) {
    if (op == '+' || op == '-') return 1;
    if (op == '*' || op == '/') return 2;
    return 0;
}

關鍵代碼框架

double compute(double a, double b, char op) {
    switch(op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return b != 0 ? a / b : 0; // 除零保護
    }
    return 0;
}

// 主循環邏輯
while (/* 還有字符 */) {
    if (isdigit(ch)) { /* 處理多位數入操作數棧 */ }
    else if (isOperator(ch)) {
        while (!opStack.empty() && precedence(opStack.top()) >= precedence(ch)) {
            // 執行棧頂運算
        }
        opStack.push(ch);
    }
}

簡化版:針對「三數兩運算符」的專用邏輯

若確定輸入格式固定為數字 運算符 數字 運算符 數字,可簡化為:

double a, b, c; char op1, op2;
scanf("%lf %c %lf %c %lf", &a, &op1, &b, &op2, &c);

double result;
if (precedence(op2) > precedence(op1)) {
    // 先算第二個運算
    double temp = compute(b, c, op2);
    result = compute(a, temp, op1);
} else {
    // 先算第一個運算
    double temp = compute(a, b, op1);
    result = compute(temp, c, op2);
}
printf("結果: %.2f", result);

避坑指南

  • 輸入解析:scanf需正確處理空格、換行,建議用%lf %c %lf %c %lf格式
  • 除零檢查:除法運算前必須判斷除數非零
  • 結合性:同優先級運算符(如連續加減)應左結合,雙棧法自然支持
  • 擴展性:雙棧法易擴展支援括號、負號、更多運算符

總結

「三數四則運算」看似簡單,實則是表達式求值的縮影。掌握雙棧法不僅能解決當前問題,更能打下編譯原理、解析器構建的基礎。建議先實現專用簡化版通過作業,再挑戰通用雙棧版提升內功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved