首页 > 代码库 > C#解析字符串公式

C#解析字符串公式

  /// <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#解析字符串公式