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#解析字符串公式的更多相关文章
- NVelocity解析字符串
之前都是先从模板文件里面读取html字符串,现在要求将模板存入数据库或缓存了,怎么办呢?在网上找了下资料,终于找到解决办法. 如下: public class NVelocityHelper { // ...
- sql 解析字符串添加到临时表中 sql存储过程in 参数输入
sql 解析字符串添加到临时表中 sql存储过程in 参数输入 解决方法 把字符串解析 添加到 临时表中 SELECT * into #临时表 FROM dbo.Func_SplitOneCol ...
- [转]用Objective-C实现简单的数学字符串公式的计算
好友第一次用写技术分享,这么多年都没见他正经的写点东西.那天突然抬头问我,Objective-C有没字符串计算的.我说,没有.后来他默默实现了,特为他转发,表示支持. ================ ...
- 转: c# 字符串公式计算
C# 自动计算字符串公式的值(三种方式) 从网络上找到这段源码,重新整理后测试通过. 有三种方式可自动计算字符串公式的值:1. 最简单的方式,由SQL语句计算2. 使用Microsoft.Javasc ...
- java代码中fastjson生成字符串和解析字符串的方法和javascript文件中字符串和json数组之间的转换方法
1.java代码中fastjson生成字符串和解析字符串的方法 List<TemplateFull> templateFulls = new ArrayList<TemplateFu ...
- JSON解析字符串
JSON解析字符串 JSON 解析字符串时,应按严格的标准,否则无法解析: str1 = '{"str":"string","number" ...
- java解析字符串拆分单独元素
有时候,需求要求传递多个字符串参数,但是方法参数已经固定为单个String,笔者在学习unity和android之间的消息传递时就遇到这个问题,所以就写了这么一个解析字符串拆分单独元素的方法. 示例: ...
- 6.游戏特别离不开脚本(3)-JS脚本操作java(2)(直接解析JS公式,并非完整JS文件或者函数)
在游戏中可以考虑数据由javabean保存,逻辑方法由JS提供. public class Bean4JS { private int id; private String name; private ...
- python,json解析字符串时ValueError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
今天写测试工具的时候,去excel取数据,用json解析字符串为字典时报错,后经调试,发现是单引号的原因,将单引号换位双引号即可 def getExcelValue_to_dic(filepath): ...
随机推荐
- 使用HttpStaus自定义返回状态
一.导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 解决Pycharm无法导入包问题 Unresolved reference
在pycharm中设置source路径 file–>setting–>project:server–>project structure 将放package的文件夹设置为source ...
- JavaSE_11_File类、递归
1.1 概述File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 1.2 构造方法 public File(String pathname ...
- 33 N皇后问题
原题网址:https://www.lintcode.com/zh-cn/old/problem/n-queens/# n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击. 给定一个整 ...
- C++ const修饰不同类型的用法
const取自constant的缩写,本意是不变的,不易改变的意思 一.修饰普通变量 const int a = 7; int b = a; //正确 a = 8; ...
- 使用 Vue.js 和 Chart.js 制作绚丽多彩的图表
本文作者:Jakub Juszczak 编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58e5e0e1a58c240ae35b ...
- myeclipse 无法部署项目到jboss服务器 部署不上去
关于myeclipse部署项目到jboss点击add deployments没有反应的问题,如图 此处点击右键,选择add deployments没有反应,原因是默认的web-root folder为 ...
- python3-常用模块之re
正则表达式 定义: 正则表达式是对字符串操作的一种逻辑公式,用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 是一种独立的规 ...
- C++【string】用法和例子
/*** * string 基础api复习 * 8 AUG 2018 */ #include <iostream> #include <string> using namesp ...
- List循环添加对象时遇到问题的解决
var temp=new handleData(); foreach(var t in data) { temp.DataValue = t.DataValue; temp.CreateTime = ...