计算字符串得出结果
程序员文章站
2022-04-08 19:53:15
需求: 在C#中对一个字符串进行计算得出结果。 例如:“1+2+66+33” 字符串中的数字可以变化,累加(这里偷懒了限定成累加)的次数可以变化。 思路/解决方案: 1. 用JavaScript中的Eval把字符串转成对象进行计算 用Com控件计算方法,引入MSScriptControl.Scrip ......
需求:
在c#中对一个字符串进行计算得出结果。
例如:“1+2+66+33”
字符串中的数字可以变化,累加(这里偷懒了限定成累加)的次数可以变化。
思路/解决方案:
1. 用javascript中的eval把字符串转成对象进行计算
用com控件计算方法,引入msscriptcontrol.scriptcontrolclass
2.用datatable().compute计算方法
3.把字符串表达式作为一个sql发到数据库计算后结果再回传到程序
4.分解字符串用 lambda表达式树动态创建一个(累加)表达式
说明:
我做了一个随机数,然后将每次随机出来的数字拼接成一个字符串展示出来。
再来解析这个字符串得出计算结果。
需要注意表达式树的方式,你的参数列表paramslist必须是 object[] 这个类型,我之前用的int[] 也可以编译但是在运行的时候会报错,你的paramenterarray应当就是构成binaryexpression的那些parameterexpression。
如果你的业务里面要用到更加复杂运算,你需要亲自来尝试。
欢迎吐槽。
代码:
using system; using system.collections.generic; using system.text; using system.linq.expressions; using system.reflection; namespace guess { class program { static void main(string[] args) { try { console.writeline(setrandomvariable(gettemplate())); } catch (exception ex) { console.writeline(ex.message); } #if debug console.read(); #endif } private static string gettemplate() { stringbuilder stb = new stringbuilder(); stb.appendline("bangladesh - oneerp {0}hr"); stb.appendline("cn - oneerp {1}hr"); stb.appendline("global - oneerp {2}hr"); stb.appendline("fe - oneerp {3}hr"); stb.appendline("uk - oneerp {4}hr"); stb.appendline("turkey - oneerp {5}hr"); stb.appendline("vietnam – oneerp {6}hr"); stb.appendline("singapore - oneerp {7}hr"); stb.appendline("cn - hz {8}hr"); stb.appendline("romania - oneerp {9}hr"); stb.appendline("thailand - oneerp {10}hr"); stb.appendline("zhejiang - oneerp {11}hr"); stb.appendline("global - oneerp sso {12}hr"); return stb.tostring(); } private static string setrandomvariable(string gettemplate) { int count = gettemplate.split('\n').length - 1; random randomvariable = new random(datetime.now.millisecond); int max = 40; stringbuilder formula = new stringbuilder(); object[] paramslist = new object[count]; for (int i = 0; i < paramslist.length; i++) { if (i == paramslist.length - 1) { paramslist[i] = max; formula.append(max); } else { paramslist[i] = available(ref max, ref formula); } } //com控件计算方法 需要目标平台x86 d找到引用的dll——属性——嵌入互操作类型——false msscriptcontrol.scriptcontrol sc = new msscriptcontrol.scriptcontrolclass(); sc.language = "javascript"; console.writeline("{0}={1}", formula.tostring(), sc.eval(formula.tostring()).tostring()); //datatable().compute计算方法 console.writeline("{0}={1}", formula.tostring(), new system.data.datatable().compute(formula.tostring(), "").tostring()); //另外有一种思路,把表达式作为一个sql发到数据库计算后结果再回传到程序。 //lambda表达式树动态创建一个累加的表达式 需要.net framework 4.5 binaryexpression binaryexpression = addexpression(count,null); console.writeline(binaryexpression); lambdaexpression lambdaexpr = expression.lambda(binaryexpression, paramenterarray); delegate de = lambdaexpr.compile(); // methodinfo method = de.method; console.writeline(de.dynamicinvoke(paramslist)); return string.format(gettemplate, paramslist); } private static int available(ref int max, ref stringbuilder formula) { int temp = 0; if (max > 0) { random randomvariable = new random(); if (max == 1) { temp = randomvariable.next(0, max + 1); } else { temp = randomvariable.next(0, max); } max = max - temp; } formula.appendformat("{0}+", temp); return temp; } static list<parameterexpression> paramenterarray=new list<parameterexpression>() ; /// <summary> /// /// </summary> /// <param name="lenght">累加次数</param> /// <param name="resultleft">默认累加表达式</param> /// <returns></returns> private static binaryexpression addexpression(int lenght, binaryexpression resultleft) { try { parameterexpression left, right; left = expression.parameter(typeof(int), string.format("left{0}", lenght) ); right = expression.parameter(typeof(int), string.format("right{0}", (lenght - 1)) ); binaryexpression result = expression.add(left, right); if (lenght > 2) { paramenterarray.add(left); paramenterarray.add(right); if (resultleft != null) result = expression.add(resultleft, addexpression(lenght - 2, result)); else result = addexpression(lenght - 2, result); } if (lenght == 2) { paramenterarray.add(left); paramenterarray.add(right); if (resultleft != null) result = expression.add(resultleft, result); else { //ignore; } } if (lenght == 1) { if (resultleft != null) { parameterexpression rexpression = expression.parameter(typeof(int), string.format("right{0}", lenght )); paramenterarray.add(rexpression); result = expression.add(resultleft, rexpression); } else { throw (new exception("当lenght等于1时,resultleft参数不能为空")); } } return result; } catch ( exception ex) { #if debug console.writeline(ex.stacktrace.tostring()); #endif throw (ex); } } } }