zoukankan      html  css  js  c++  java
  • 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/

    下面给出实现代码:

  • 相关阅读:
    从零起步搭建Hadoop单机和伪分布式开发环境图文教程
    使用DOM技术操纵文档
    求数组的子数组之和的最大值
    设计时(DesignTime)和运行时(RunTime)的区别
    ubuntu上ssh客户端应用
    创建一个简单的基于MVC的Django项目
    终结点与服务寄宿
    Google文件系统(GFS)翻译学习
    模板引擎开发(二)值标签的处理
    移动App服务端架构设计
  • 原文地址:https://www.cnblogs.com/linsu/p/4179096.html
Copyright © 2011-2022 走看看