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/

下面给出实现代码:

时间: 2024-11-19 11:54:30

C#解析字符串公式的相关文章

Javascript 解析字符串生成 XML DOM 对象。

Javascript 接收字符串生成 XML DOM 对象.实测对 Firefox .IE6 有效.可用于解析 ajax 的服务器响应结果,也可用于解析自定义字符串.?1. [代码]函数   ppt模版  /** * Parses DOM from XML text.<br /> *  * @author Typhoon.Free.Wolf * @version 2014-02-28_15-51 * @param blDebugFlag *      - Debug flag: true, f

关于解析字符串

nodejs中提供的解析字符串模块:首先需要映入url模块和查询字符串模块 其中url提供的字符串解析方法为parse const url = require('url'); const querystring = require('querystring'); 'use strict'; const http = require('http'); const url = require('url'); const querystring = require('querystring'); co

java解析字符串拆分单独元素

有时候,需求要求传递多个字符串参数,但是方法参数已经固定为单个String,笔者在学习unity和android之间的消息传递时就遇到这个问题,所以就写了这么一个解析字符串拆分单独元素的方法. 示例:“@[email protected]@apple” 解析为: my red apple 1 package cutstring; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Scanner;

sql 解析字符串添加到临时表中 sql存储过程in 参数输入

sql 解析字符串添加到临时表中  sql存储过程in 参数输入 解决方法 把字符串解析 添加到 临时表中 SELECT * into #临时表   FROM dbo.Func_SplitOneColumnTabel('001,gf', ',') select * from 表 where ID in (select id from 临时表) Create function [dbo].[Func_SplitOneColumnTabel] (@str nvarchar(max),@split v

解析字符串

解析字符串:封装一个解析字符串的工具类,方便调用 public static String readStream(InputStream is){  try{       ByteArrayOutputStream baos = new ByteArrayOutputStream();       int len = 0;       byte[] buffer = new byte[1024];       while((len = is.read(buffer))!=-1){       

Json解析字符串j简单实例

Json解析字符串实例,解析内容为: {"info":[{"code":"C","key":"028","nearest":"NO","value":"???"},{"code":"N","key":"0771","nearest"

cjson源代码解读(三) 解析字符串、数字、数组、对象

1.  解析数字 static const char *parse_number(cJSON *item,const char *num) { double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; if (*num=='-') sign=-1,num++; /* Has sign? */ if (*num=='0') num++; /* is zero */ if (*num>='1' && *num<='9') do

JSON解析字符串

JSON 解析字符串时,应按严格的标准,否则无法解析: str1 = '{"str":"string","number":123,"logic":true}'; str2 =  ''{'str':'string','number':123,'logic':true}''; str1 str2 都满足javascript 字符串的定义要求. 但是str2 无法满足JSON对字符串的要求: json字符串的格式一定要标准,key和

jsoncpp封装和解析字符串、数字、布尔值和数组

使用jsoncpp进行字符串.数字.布尔值和数组的封装与解析. 1)下载jsoncpp的代码库 百度网盘地址 :http://pan.baidu.com/s/1ntqQhIT 2)解压缩文件 jsoncpp.rar unzip jsoncpp.rar 3)修改jsoncpp/src/main.cpp文件 vim src/main.cpp 1 #include <string> 2 #include <json/json.h> 3 #include "stdio.h&quo