如何在C#中运行数学表达式字符串
方法1:利用DataTable中的Compute方法
1 string expression = "1+2*3";
2 DataTable eval = new DataTable();object result = eval.Compute(expression, “”);
方法2:利用xPath表达式

1 publicstaticdoubleEvaluate(string expression)
2 {
3 return(double)newSystem.Xml.XPath.XPathDocument
4 (newStringReader("<r/>")).CreateNavigator().Evaluate
5 (string.Format("number({0})",new
6 System.Text.RegularExpressions.Regex(@"([\+\-\*])")
7 .Replace(expression," ${1} ")
8 .Replace("/"," div ")
9 .Replace("%"," mod ")));
10 }

//方法3:利用python里面的计算表达式方法 该方法的内容被博客园吃掉了。懒得找了
方法4:在网上找了一个计算表达式的类库

1 /**/
2 /// <summary>
3 /// 动态求值
4 /// </summary>
5 public class Evaluator
6 {
7 /**/
8 /// <summary>
9 /// 计算结果,如果表达式出错则抛出异常
10 /// </summary>
11 /// <param name="statement">表达式,如"1+2+3+4"</param>
12 /// <returns>结果</returns>
13 public static object Eval(string statement)
14 {
15 if (statement.Trim() != string.Empty)
16 {
17 Evaluator evaluator = new Evaluator();
18 return evaluator.GetFormulaResult(statement);
19 }
20 else
21 {
22 return null;
23 }
24 }
25
26
27 private object GetFormulaResult(string s)
28 {
29 if (s == "")
30 {
31 return null;
32 }
33 string S = BuildingRPN(s);
34
35 string tmp = "";
36 System.Collections.Stack sk = new System.Collections.Stack();
37
38 char c = ' ';
39 System.Text.StringBuilder Operand = new System.Text.StringBuilder();
40 double x, y;
41 for (int i = 0;
42 i < S.Length;
43 i++)
44 {
45 c = S[i];
46 //added c==',' for germany culture
47 if (char.IsDigit(c) || c == '.' || c == ',')
48 {
49 //数据值收集.
50 Operand.Append(c);
51 }
52 else if (c == ' ' && Operand.Length > 0)
53 {
54 #region 运算数转换
55 try
56 {
57 tmp = Operand.ToString();
58 if (tmp.StartsWith("-"))//负数的转换一定要小心...它不被直接支持.
59 {
60 //现在我的算法里这个分支可能永远不会被执行.
61 sk.Push(-((double)Convert.ToDouble(tmp.Substring(1, tmp.Length - 1))));
62 }
63 else
64 {
65 sk.Push(Convert.ToDouble(tmp));
66 }
67 }
68 catch
69 {
70 return null; //
71 }
72 Operand = new System.Text.StringBuilder();
73 #endregion
74 }
75 else if (c == '+'//运算符处理.双目运算处理.
76 || c == '-'
77 || c == '*'
78 || c == '/'
79 || c == '%'
80 || c == '^')
81 {
82 #region 双目运算
83 if (sk.Count > 0)/*如果输入的表达式根本没有包含运算符.或是根本就是空串.这里的逻辑就有意义了.*/
84 {
85 y = (double)sk.Pop();
86 }
87 else
88 {
89 sk.Push(0);
90 break;
91 }
92 if (sk.Count > 0)
93 x = (double)sk.Pop();
94 else
95 {
96 sk.Push(y);
97 break;
98 }
99 switch (c)
100 {
101 case '+':
102 sk.Push(x + y);
103 break;
104 case '-':
105 sk.Push(x - y);
106 break;
107 case '*':
108 if (y == 0)
109 {
110 sk.Push(x * 1);
111 }
112 else
113 {
114 sk.Push(x * y);
115 }
116 break;
117 case '/':
118 if (y == 0)
119 {
120 sk.Push(x / 1);
121 }
122 else
123 {
124 sk.Push(x / y);
125 }
126 break;
127 case '%':
128 sk.Push(x % y);
129 break;
130 case '^'://
131 if (x > 0)//
132 {
133 //我原本还想,如果被计算的数是负数,又要开真分数次方时如何处理的问题.后来我想还是算了吧.
134 sk.Push(System.Math.Pow(x, y));
135 //
136 }
137 //
138 else//
139 {
140 //
141 double t = y;
142 //
143 string ts = "";
144 //
145 t = 1 / (2 * t);
146 //
147 ts = t.ToString();
148 //
149 if (ts.ToUpper().LastIndexOf('E') > 0)//
150 {
151 //
152 ;
153 //
154 }
155 //
156 }
157 break;
158 }
159 #endregion
160 }
161 else if (c == '!')//单目取反. )
162 {
163 sk.Push(-((double)sk.Pop()));
164 }
165 }
166 if (sk.Count > 1)
167 {
168 return null;//;
169 }
170 if (sk.Count == 0)
171 {
172 return null;//;
173 }
174 return sk.Pop();
175 }
176 /**/
177 /// <summary>
178 ///
179 /// </summary>
180 private string BuildingRPN(string s)
181 {
182 System.Text.StringBuilder sb = new System.Text.StringBuilder(s);
183 System.Collections.Stack sk = new System.Collections.Stack();
184 System.Text.StringBuilder re = new System.Text.StringBuilder();
185
186 char c = ' ';
187 //sb.Replace( " ","" );
188 //一开始,我只去掉了空格.后来我不想不支持函数和常量能滤掉的全OUT掉.
189 for (int i = 0;
190 i < sb.Length;
191 i++)
192 {
193 c = sb[i];
194 //added c==',' for german culture
195 if (char.IsDigit(c) || c == ',')//数字当然要了.
196 re.Append(c);
197 //if( char.IsWhiteSpace( c )||
198 char.IsLetter(c);//如果是空白,那么不要.现在字母也不要.
199 //continue;
200 switch (c)//如果是其它字符...列出的要,没有列出的不要.
201 {
202 case '+':
203 case '-':
204 case '*':
205 case '/':
206 case '%':
207 case '^':
208 case '!':
209 case '(':
210 case ')':
211 case '.':
212 re.Append(c);
213 break;
214 default:
215 continue;
216 }
217 }
218 sb = new System.Text.StringBuilder(re.ToString());
219 #region 对负号进行预转义处理.负号变单目运算符求反.
220 for (int i = 0; i < sb.Length - 1; i++)
221 if (sb[i] == '-' && (i == 0 || sb[i - 1] == '('))
222 sb[i] = '!';
223 //字符转义.
224 #endregion
225 #region 将中缀表达式变为后缀表达式.
226 re = new System.Text.StringBuilder();
227 for (int i = 0;
228 i < sb.Length;
229 i++)
230 {
231 if (char.IsDigit(sb[i]) || sb[i] == '.')//如果是数值.
232 {
233 re.Append(sb[i]);
234 //加入后缀式
235 }
236 else if (sb[i] == '+'
237 || sb[i] == '-'
238 || sb[i] == '*'
239 || sb[i] == '/'
240 || sb[i] == '%'
241 || sb[i] == '^'
242 || sb[i] == '!')//.
243 {
244 #region 运算符处理
245 while (sk.Count > 0) //栈不为空时
246 {
247 c = (char)sk.Pop();
248 //将栈中的操作符弹出.
249 if (c == '(') //如果发现左括号.停.
250 {
251 sk.Push(c);
252 //将弹出的左括号压回.因为还有右括号要和它匹配.
253 break;
254 //中断.
255 }
256 else
257 {
258 if (Power(c) < Power(sb[i]))//如果优先级比上次的高,则压栈.
259 {
260 sk.Push(c);
261 break;
262 }
263 else
264 {
265 re.Append(' ');
266 re.Append(c);
267 }
268 //如果不是左括号,那么将操作符加入后缀式中.
269 }
270 }
271 sk.Push(sb[i]);
272 //把新操作符入栈.
273 re.Append(' ');
274 #endregion
275 }
276 else if (sb[i] == '(')//基本优先级提升
277 {
278 sk.Push('(');
279 re.Append(' ');
280 }
281 else if (sb[i] == ')')//基本优先级下调
282 {
283 while (sk.Count > 0) //栈不为空时
284 {
285 c = (char)sk.Pop();
286 //pop Operator
287 if (c != '(')
288 {
289 re.Append(' ');
290 re.Append(c);
291 //加入空格主要是为了防止不相干的数据相临产生解析错误.
292 re.Append(' ');
293 }
294 else
295 break;
296 }
297 }
298 else
299 re.Append(sb[i]);
300 }
301 while (sk.Count > 0)//这是最后一个弹栈啦.
302 {
303 re.Append(' ');
304 re.Append(sk.Pop());
305 }
306 #endregion
307 re.Append(' ');
308 return FormatSpace(re.ToString());
309 //在这里进行一次表达式格式化.这里就是后缀式了.
310 }
311
312 /// <summary>
313 /// 优先级别测试函数.
314 /// </summary>
315 /// <param name="opr"></param>
316 /// <returns></returns>
317 private static int Power(char opr)
318 {
319 switch (opr)
320 {
321 case '+':
322 case '-':
323 return 1;
324 case '*':
325 case '/':
326 return 2;
327 case '%':
328 case '^':
329 case '!':
330 return 3;
331 default:
332 return 0;
333 }
334 }
335
336 /// <summary>
337 /// 规范化逆波兰表达式.
338 /// </summary>
339 /// <param name="s"></param>
340 /// <returns></returns>
341 private static string FormatSpace(string s)
342 {
343 System.Text.StringBuilder ret = new System.Text.StringBuilder();
344 for (int i = 0;
345 i < s.Length;
346 i++)
347 {
348 if (!(s.Length > i + 1 && s[i] == ' ' && s[i + 1] == ' '))
349 ret.Append(s[i]);
350 else
351 ret.Append(s[i]);
352 }
353 return ret.ToString();
354 //.Replace( '!','-' );
355 }
356 }

如何在C#中运行数学表达式字符串的更多相关文章
- Oracle中有关数学表达式的语法
Oracle中有关数学表达式的语法 三角函数 SIN ASIN SINHCOS ACOS COSHTA ...
- Nodejs的安装配置及如何在sublimetext2中运行js
Nodejs的安装配置及如何在sublimetext2中运行js听语音 | 浏览:4554 | 更新:2015-06-16 11:29 Nodejs的安装配置及如何在sublimetext2中运行js ...
- 如何在xampp中运行php文件 (WINDOWS)
from:http://blog.sina.com.cn/s/blog_5e87822501011os2.html 入门: 如何在xampp中运行php文件 (WINDOWS) 安装XAMPP启动ap ...
- [转帖]如何在VirtualBox中运行macOS Catalina Beta版本
如何在VirtualBox中运行macOS Catalina Beta版本 secist2019-08-03共2179人围观系统安全 https://www.freebuf.com/articles/ ...
- 理解CSS中的数学表达式calc()
前面的话 数学表达式calc()是CSS中的函数,主要用于数学运算.使用calc()为页面元素布局提供了便利和新的思路.本文将介绍calc()的相关内容 定义 数学表达式calc()是calculat ...
- css中的数学表达式calc()
前言 数学表达式calc()是CSS中的函数,主要用于数学运算.使用calc()为页面元素布局提供了便利和新的思路. 概念 数学表达式calc()是calculate计算的缩写,它允许使用+.-.*. ...
- Zookeeper客户端cli_st为何在crontab中运行不正常?
实践中,发现直接在命令行终端运行cli_st时,能够得到预期的结果,但一将它放到crontab中,则只收到: bye 相关的一段clit_st源代码如下: if (FD_ISSET(, &rf ...
- 如何在linux中运行sql文件
1.在linux中进入sql命令行 mysql -u root -p 输入密码 2.假设home下面有a.sql文件 先得use databasename,要不会报错 “No Database S ...
- 如何在RichTextBox中改变多个字符串的颜色以及字体
目标:传入目标富文本框以及需要查找的字符串,如果文本框中存在字符串,则改变其颜色和字体 可能因为这个问题比较简单,在网上找了很久,也没有一个好的方法.少有的一些方法,也只是改变第一个找到的字符串的颜色 ...
随机推荐
- ffmpeg中关于EAGAIN的理解及非阻塞IO
ffmpeg为在linux下开发的开源音视频框架,所以经常会碰到很多错误(设置errno),其中EAGAIN是其中比较常见的一个错误(比如用在非阻塞操作中). try again,从字面上来看,是提 ...
- 【剑指Offer】64、滑动窗口的最大值
题目描述: 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{ ...
- vue.js层叠轮播
最近写公司项目有涉及到轮播banner,一般的ui框架无法满足产品需求:所以自己写了一个层叠式轮播组件:现在分享给大家: 主要技术栈是vue.js ;javascript;jquery:确定实现思路因 ...
- 亚马逊免费服务器搭建Discuz!论坛过程(三)
参考文章:http://faq.comsenz.com/library/system/env/env_linux.htm 参考但是不要完全按照上述文章,不然很可能出错. 尤其不要init 6 重启,我 ...
- nginx下部署showdoc
1. 安装nginx服务器sudo apt-get install nginx -y 2. 启动服务sudo service nginx start 3. 安装php环境 sudo apt-get i ...
- 2019-04-18 Python Base 1
C:\Users\Jeffery1u>python Python 3.7.3 (default, Mar 27 2019, 17:13:21) [MSC v.1915 64 bit (AMD64 ...
- 阿里云对象存储服务,OSS使用经验总结,图片存储,分页查询
阿里云OSS-使用经验总结,存储,账号-权限,分页,缩略图,账号切换 最近项目中,需要使用云存储,最后选择了阿里云-对象存储服务OSS.总的来说,比较简单,但是仍然遇到了几个问题,需要总结下. 1.O ...
- 洛谷 P1198 BZOJ 1012 [JSOI2008]最大数
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
- HDU 5355 Cake
HDU 5355 Cake 更新后的代码: 今天又一次做这道题的时候想了非常多种思路 最后最终想出了自觉得完美的思路,结果却超时 真的是感觉自己没救了 最后加了记忆化搜索,AC了 好了先说下思路吧.不 ...
- 使用URL在线语音合成
近期一直在做手机的项目,用到了语音合成与识别的功能.就找了几个网址做了分析,这里只实现了内容的合成.并不包括语音识别. 首先看一下谷歌的语音合成地址: http://translate.google. ...