方法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#中运行数学表达式字符串的更多相关文章

  1. Oracle中有关数学表达式的语法

    Oracle中有关数学表达式的语法 三角函数 SIN               ASIN              SINHCOS             ACOS           COSHTA ...

  2. Nodejs的安装配置及如何在sublimetext2中运行js

    Nodejs的安装配置及如何在sublimetext2中运行js听语音 | 浏览:4554 | 更新:2015-06-16 11:29 Nodejs的安装配置及如何在sublimetext2中运行js ...

  3. 如何在xampp中运行php文件 (WINDOWS)

    from:http://blog.sina.com.cn/s/blog_5e87822501011os2.html 入门: 如何在xampp中运行php文件 (WINDOWS) 安装XAMPP启动ap ...

  4. [转帖]如何在VirtualBox中运行macOS Catalina Beta版本

    如何在VirtualBox中运行macOS Catalina Beta版本 secist2019-08-03共2179人围观系统安全 https://www.freebuf.com/articles/ ...

  5. 理解CSS中的数学表达式calc()

    前面的话 数学表达式calc()是CSS中的函数,主要用于数学运算.使用calc()为页面元素布局提供了便利和新的思路.本文将介绍calc()的相关内容 定义 数学表达式calc()是calculat ...

  6. css中的数学表达式calc()

    前言 数学表达式calc()是CSS中的函数,主要用于数学运算.使用calc()为页面元素布局提供了便利和新的思路. 概念 数学表达式calc()是calculate计算的缩写,它允许使用+.-.*. ...

  7. Zookeeper客户端cli_st为何在crontab中运行不正常?

    实践中,发现直接在命令行终端运行cli_st时,能够得到预期的结果,但一将它放到crontab中,则只收到: bye 相关的一段clit_st源代码如下: if (FD_ISSET(, &rf ...

  8. 如何在linux中运行sql文件

    1.在linux中进入sql命令行 mysql -u root -p   输入密码 2.假设home下面有a.sql文件 先得use databasename,要不会报错 “No Database S ...

  9. 如何在RichTextBox中改变多个字符串的颜色以及字体

    目标:传入目标富文本框以及需要查找的字符串,如果文本框中存在字符串,则改变其颜色和字体 可能因为这个问题比较简单,在网上找了很久,也没有一个好的方法.少有的一些方法,也只是改变第一个找到的字符串的颜色 ...

随机推荐

  1. SLAM: 关于Orb_SLAM的使用小综述

    0.ORB_SLAM的官方网站:http://webdiis.unizar.es/~raulmur/orbslam/ 1. 参考知乎上对 orb-slam 的评价:orb-slam在众多SLAM方法中 ...

  2. MFC 添加文件路径 遍历文件

    .添加MFC选择文件路径,使用MessageBox显示信息. void CMyCalLawsDlg::OnBnClickedAddfolder() { wchar_t* p; wchar_t szPa ...

  3. [CefSharp] 如何在JavaScript中调用C#代码

    本例在WinForms下实现,具体流程与WPF一致. 本例仅供调用示例,不代表正常业务书写流程. 1. 创建WinForms项目,并将项目属性设置为x86平台 此处预先设置,避免引用时报错,再花更多的 ...

  4. 常用的 CSS 技巧

    1. 黑白图像 这段代码会让你的彩色照片显示为黑白照片,是不是很酷? img.desaturate { filter: grayscale(%); -webkit-filter: grayscale( ...

  5. Python基础知识-Day4

    一.函数关键字关键字是Python内置的,具有特殊意义的标识符,自定义标识符命名时不可与之重复.可以通过以下代码查看Python内置的关键字内容. import keyword print(keywo ...

  6. TCP中的RST标志(Reset)详解

    在谈RST攻击前,必须先了解TCP:如何通过三次握手建立TCP连接.四次握手怎样把全双工的连接关闭掉.滑动窗口是怎么传输数据的.TCP的flag标志位里RST在哪些情况下出现.下面我会画一些尽量简化的 ...

  7. python tkinter模块小工具界面

    代码 #-*-coding:utf-8-*- import os from tkinter import * root=Tk() root.title('小工具') #清空文本框内容 def clea ...

  8. 洛谷P1192 台阶问题【dp递归】

    有NN级的台阶,你一开始在底部,每次可以向上迈最多KK级台阶(最少11级),问到达第NN级台阶有多少种不同方式. 输入输出格式 输入格式: 两个正整数N,K. 输出格式: 一个正整数,为不同方式数,由 ...

  9. 洛谷P1464 Function

    对于一个递归函数w(a,b,c)w(a,b,c) 如果a \le 0a≤0 or b \le 0b≤0 or c \le 0c≤0就返回值11. 如果a>20a>20 or b>20 ...

  10. Nginx面试中最常见的18道题 抱佛脚必备

    Nginx的并发能力在同类型网页服务器中的表现,相对而言是比较好的,因此受到了很多企业的青睐,我国使用Nginx网站的知名用户包括腾讯.淘宝.百度.京东.新浪.网易等等.Nginx是网页服务器运维人员 ...