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

NYOJ 表達式求值:雙棧法實現四則運算與括號優先級解析

     編輯:關於C++

題目大意

輸入以 = 結尾的算術表達式(含 + - * / ( ),數值為非負實數),輸出計算結果保留兩位小數。多組測試。

核心算法:運算符優先級雙棧法

維護兩個棧:
- num:操作數棧(double)
- op:運算符棧(char),初始壓入 '=' 作為哨兵

運算符優先級比較表

棧頂 \ 當前+ -* /()=
+ -><<>>
* />><>>
(<<<=錯誤
=<<<錯誤=

<:當前優先級高,壓棧。
>:棧頂優先級高/等,彈出計算。
=:匹配成功,彈出哨兵。

處理流程

  1. 掃描字符串,識別數字(含小數點)壓入 num。
  2. 遇到運算符,與棧頂比較優先級:
char cmp = compare(op.top(), cur);
if (cmp == '<') op.push(cur);
else if (cmp == '>') {
    double b = num.top(); num.pop();
    double a = num.top(); num.pop();
    num.push(calc(a, op.top(), b));
    op.pop();
    // 當前運算符不進棧,指針不動,下輪再比較
} else if (cmp == '=') op.pop();  // 匹配括號或結束
  1. 掃描結束,num.top() 即為結果。

關鍵代碼片段

double calc(double a, char op, double b) {
    switch(op) {
        case '+': return a+b;
        case '-': return a-b;
        case '*': return a*b;
        case '/': return a/b;  // 題目保證除數非 0
    }
    return 0;
}

char compare(char top, char cur) {
    if (top == '+' || top == '-') {
        if (cur == '*' || cur == '/' || cur == '(') return '<';
        return '>';
    }
    if (top == '*' || top == '/') {
        if (cur == '(') return '<';
        return '>';
    }
    if (top == '(') {
        if (cur == ')') return '=';
        return '<';
    }
    if (top == ')') return '>';
    if (top == '=') {
        if (cur == '=') return '=';
        return '<';
    }
    return '>'; // default
}

避坑指南

  1. 數字解析:用 sscanf 或手寫狀態機讀取完整浮點數(含小數點)。
  2. 優先級表必須精確,特別是 ( 在棧中優先級最低,遇 ) 才匹配。
  3. 輸出格式:printf("%.2f\n", ans) 自動四捨五入保留兩位小數。
  4. 輸入可能含多行測試,用 while(k--) 循環。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved