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

C# 算術表達式求值器:逆波蘭表示法 (RPN) 完整實作與負號預處理技巧

     編輯:關於C#

核心演算法:中綴 → 後綴 (RPN) → 堆疊求值

  1. 詞法掃描:保留數字、小數點、運算子 +-*/%^!、括號,其餘捨棄。
  2. 負號預處理:將一元負號(行首或 ( 後)替換為 !,避免與減號混淆。
  3. Shunting-yard 產生 RPN:運算子優先級 !^% > */ > +-,左括號入棧,右括號彈出至左括號。
  4. RPN 求值:遇數字入棧,遇二元運算子彈兩數運算再入棧,遇一元 ! 彈一數取反。

關鍵程式碼結構


public sealed class SimpleRPN
{
    // 1. 建構 RPN
    private static string BuildingRPN(string s) { ... }

    // 2. 運算子優先級
    private static int Power(char op) { ... }

    // 3. 計算 RPN
    public static string ComputeRPN(string expr) { ... }

    // 4. 格式化空白
    private static string FormatSpace(string s) { ... }
}

負號處理細節


// 預處理:行首或 '(' 後的 '-' 改為 '!'
for (int i = 0; i < sb.Length - 1; i++)
    if (sb[i] == '-' && (i == 0 || sb[i-1] == '('))
        sb[i] = '!';

// 求值時處理一元 '!'
else if (c == '!')
    stack.Push(-(double)stack.Pop());

支援功能與限制

  • ✅ 四則運算、乘方 ^、取模 %、一元正負號
  • ✅ 多位數、浮點數、巢狀括號
  • ❌ 三角函數、常數 (π, e)、變數、三元運算子
  • ❌ -(3+5) 原作者 w3eval 亦有此 Bug,本實作透過 ! 解決

測試案例


ComputeRPN("(6+9-8+5-8)*(2+5+8)/7+5")           // 正確
ComputeRPN("(-3+4+9)*(-3)*7/(-5*2)-(6+9)...")   // 負號巢狀正確
ComputeRPN("1+2+3+4+5+6+7+8+9")                 // 45
ComputeRPN("1*2*3*4*5*6*7*8*9")                 // 362880

擴充指南

  1. 新增運算子:在 Power() 加入優先級,BuildingRPN 的 switch 加入字元,ComputeRPN 加入 case 邏輯。
  2. 支援函數:詞法階段識別字母序列 → 查表取得委派 → 視為運算子處理(需處理參數逗號與括號)。
  3. 效能優化:將 char 改為 byte、避免 StringBuilder 重複配置、改用 Span<char> 零拷貝解析。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved