C#解析字串公式

來源:互聯網
上載者:User

標籤:

  /// <summary>        /// 中綴運算式到逆波蘭運算式的轉換及求值         /// </summary>        public class RpnExpression        {          #region  定義屬性            int Top = -1;            #endregion          /// <summary>        /// 檢查中綴運算式是否合法        /// </summary>        /// <param name="exp"></param>        /// <returns></returns>          public  bool IsRight(string exp)            {                string pMatch = @"\([^\(^\)]+\)";//匹配最“內”層括弧及運算式                string numberMatch = @"\d+(\.\d+)?";//匹配數字                string exMatch = @"^0([-+*/]0)*$";//匹配無括弧的、用0替換所有的數字後的運算式                exp = Regex.Replace(exp, numberMatch, "0");//為簡化檢測,用0替換所有的數字                while (Regex.IsMatch(exp, pMatch))                {                    foreach (Match match in Regex.Matches(exp, pMatch))                    {                        string tmp = match.Value;                        tmp = tmp.Substring(1, tmp.Length - 2);//去掉 "("和 ")"                        if (!Regex.IsMatch(tmp, exMatch)) return false;                    }                    exp = Regex.Replace(exp, pMatch, "0");//將最內層的括弧及括弧內運算式直接用一個0代替                }                return Regex.IsMatch(exp, exMatch);            }          #region 產生逆波蘭運算式        /// <summary>        /// 擷取逆波蘭運算式        /// </summary>        /// <param name="exp"></param>        /// <returns></returns>        public  string RpnExp(string exp)        {            string S = ""; //尾碼             char[] Operators = new char[exp.Length];                       for (int i = 0; i < exp.Length; i++)            {                char C = exp[i];                switch (C)                {                    case ‘ ‘: //忽略空格                         break;                    case ‘+‘: //操作符                     case ‘-‘:                        while (Top >= 0) //棧不為空白時                         {                            char c = Operators[Top--]; //pop Operator                             if (c == ‘(‘)                            {                                Operators[++Top] = c; //push Operator                                 break;                            }                            else                            {                                S = S + c;                            }                        }                        Operators[++Top] = C; //push Operator                         S += " ";                        break;                    case ‘*‘: //忽略空格                     case ‘/‘:                        while (Top >= 0) //棧不為空白時                         {                            char c = Operators[Top--]; //pop Operator                             if (c == ‘(‘)                            {                                Operators[++Top] = c; //push Operator                                 break;                            }                            else                            {                                if (c == ‘+‘ || c == ‘-‘)                                {                                    Operators[++Top] = c; //push Operator                                     break;                                }                                else                                {                                    S = S + c;                                }                            }                        }                        Operators[++Top] = C; //push Operator                         S += " ";                        break;                    case ‘(‘:                        Operators[++Top] = C;                        S += " ";                        break;                    case ‘)‘:                        while (Top >= 0) //棧不為空白時                         {                            char c = Operators[Top--]; //pop Operator                             if (c == ‘(‘)                            {                                break;                            }                            else                            {                                S = S + c;                            }                        }                        S += " ";                        break;                    default:                        S = S + C;                        break;                }            }            while (Top >= 0)            {                S = S + Operators[Top--]; //pop Operator             }            return S;        }                   #endregion          #region 取逆波蘭運算式的值        /// <summary>        /// 擷取逆波蘭運算式的值        /// </summary>        /// <param name="rpnExp"></param>        /// <returns></returns>        public  double GetValueByRpn(string rpnExp)        {            //尾碼運算式計算             double[] Operands = new double[rpnExp.Length];            double x, y, v;            Top = -1;            string Operand = "";            for (int i = 0; i < rpnExp.Length; i++)            {                char c = rpnExp[i];                if ((c >= ‘0‘ && c <= ‘9‘) || c == ‘.‘)                {                    Operand += c;                }                if ((c == ‘ ‘ || i == rpnExp.Length - 1) && Operand != "") //Update                 {                    Operands[++Top] = System.Convert.ToDouble(Operand); //push Operands                     Operand = "";                }                if (c == ‘+‘ || c == ‘-‘ || c == ‘*‘ || c == ‘/‘)                {                    if ((Operand != ""))                    {                        Operands[++Top] = System.Convert.ToDouble(Operand); //push Operands                         Operand = "";                    }                    y = Operands[Top--]; //pop 雙目運算子的第二運算元 (後進先出)注意運算元順序對除法的影響                     x = Operands[Top--]; //pop 雙目運算子的第一運算元                     switch (c)                    {                        case ‘+‘:                            v = x + y;                            break;                        case ‘-‘:                            v = x - y;                            break;                        case ‘*‘:                            v = x * y;                            break;                        case ‘/‘:                            v = x / y; // 第一運算元 / 第二運算元 注意運算元順序對除法的影響                             break;                        default:                            v = 0;                            break;                    }                    Operands[++Top] = v; //push 中間結果再次入棧                 }            }            v = Operands[Top--]; //pop 最終結果             return v;        }      #endregion        }

 

1.先說明下這個實現演算法--逆波蘭運算式

 

運算式一般由運算元(Operand)、運算子(Operator)組成,例如算術運算式中,通常把運算子放在兩個運算元的中間,

這稱為中綴運算式(Infix Expression),如A+B。

波蘭數學家Jan Lukasiewicz提出了另一種數學標記法,它有兩種表示形式:

把運算子寫在運算元之前,稱為波蘭運算式(Polish Expression)或首碼運算式(Prefix Expression),如+AB;

把運算子寫在運算元之後,稱為逆波蘭運算式(Reverse Polish Expression)或尾碼運算式(Suffix Expression),如AB+;

其中,逆波蘭運算式在編譯技術中有著普遍的應用。

演算法:

一、 將中綴運算式轉換成尾碼運算式演算法:

1、從左至右掃描一中綴運算式。

2、若讀取的是運算元,則判斷該運算元的類型,並將該運算元存入運算元堆棧

3、若讀取的是運算子

  (1) 該運算子為左括弧"(",則直接存入運算子堆棧。

  (2) 該運算子為右括弧")",則輸出運算子堆棧中的運算子到運算元堆棧,直到遇到左括弧為止。

  (3) 該運算子為非括弧運算子:

      (a) 若運算子堆棧棧頂的運算子為括弧,則直接存入運算子堆棧。

      (b) 若比運算子堆棧棧頂的運算子優先順序高或相等,則直接存入運算子堆棧。

      (c) 若比運算子堆棧棧頂的運算子優先順序低,則輸出棧頂運算子到運算元堆棧,並將當前運算子壓入運算子堆棧。

4、當運算式讀取完成後運算子堆棧中尚有運算子時,則依序取出運算子到運算元堆棧,直到運算子堆棧為空白

樣本:

  (1.2+3.5)*2/4 =>1.2 3.5+ 2* 4/

下面給出實現代碼:

 

C#解析字串公式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.