欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

计算字符串得出结果

程序员文章站 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);
            }
        }
    }
}