代码之家  ›  专栏  ›  技术社区  ›  Arsen Mkrtchyan

计算数学表达式的最佳和最短方法

  •  18
  • Arsen Mkrtchyan  · 技术社区  · 16 年前

    有许多算法可以计算表达式,例如:

    1. By Recursive Descent
    2. Shunting-yard algorithm
    3. Reverse Polish notation

    8 回复  |  直到 13 年前
        1
  •  19
  •   LukeH    11 年前

    eval

    using Microsoft.JScript;        // needs a reference to Microsoft.JScript.dll
    using Microsoft.JScript.Vsa;    // needs a reference to Microsoft.Vsa.dll
    
    // ...
    
    string expr = "7 + (5 * 4)";
    Console.WriteLine(JScriptEval(expr));    // displays 27
    
    // ...
    
    public static double JScriptEval(string expr)
    {
        // error checking etc removed for brevity
        return double.Parse(Eval.JScriptEvaluate(expr, _engine).ToString());
    }
    
    private static readonly VsaEngine _engine = VsaEngine.CreateEngine();
    
        2
  •  13
  •   Joren    16 年前

    CodeSnippetCompileUnit

    • 系统。CodeDom;

    string source = @"
    class MyType
    {
        public static int Evaluate(<!parameters!>)
        {
            return <!expression!>;
        }
    }
    ";
    
    string parameters = "int a, int b, int c";
    string expression = "a + b * c";
    
    string finalSource = source.Replace("<!parameters!>", parameters).Replace("<!expression!>", expression);
    
    CodeSnippetCompileUnit compileUnit = new CodeSnippetCompileUnit(finalSource);
    CodeDomProvider provider = new CSharpCodeProvider();
    
    CompilerParameters parameters = new CompilerParameters();
    
    CompilerResults results = provider.CompileAssemblyFromDom(parameters, compileUnit);
    
    Type type = results.CompiledAssembly.GetType("MyType");
    MethodInfo method = type.GetMethod("Evaluate");
    
    // The first parameter is the instance to invoke the method on. Because our Evaluate method is static, we pass null.
    int result = (int)method.Invoke(null, new object[] { 4, -3, 2 });
    

        3
  •  3
  •   Thomas Levesque    16 年前
        4
  •  3
  •   Roel    16 年前

    .

    Eval

    class JsMath
    {
        static function Eval(expression : String) : double
        {
            return eval(expression);
        };
    }
    

    将其编译成类库:

    jsc /t:library JsMath.js
    

    double result = JsMath.Eval(expression);
    
        5
  •  3
  •   Jalali Shakib    13 年前

    check it out here

    (我们用它来设置“人类可读”的业务规则,数据由SQL server数据库提供)

    示例可用,开发人员提供了非常好的支持(查看网站论坛)。

        6
  •  1
  •   Community Mohan Dere    9 年前

    我认为这是最好的办法。 Petar Repac's answer 使用DataColumn对象的'expression'参数可以非常轻松地解决这个问题:

    static double Evaluate(string expression)
    {
        var loDataTable = new DataTable();
        var loDataColumn = new DataColumn("Eval", typeof(double), expression);
        loDataTable.Columns.Add(loDataColumn);
        loDataTable.Rows.Add(0);
        return (double)(loDataTable.Rows[0]["Eval"]);
    }
    
        7
  •  0
  •   Giorgi    6 年前

    Math-Expression-Evaluator 2.5+5.9 , 17.89-2.47+7.16 , 5/2/2+1.5*3+4.58 (((9-6/2)*2-4)/2-6-1)/(2+24/(2+4))

    var a = 6;
    var b = 4.32m;
    var c = 24.15m;
    var engine = new ExpressionEvaluator();
    engine.Evaluate("(((9-a/2)*2-b)/2-a-1)/(2+c/(2+4))", new { a, b, c});
    

    dynamic dynamicEngine = new ExpressionEvaluator();
    
    var a = 6;
    var b = 4.5m;
    var c = 2.6m;
    
    dynamicEngine.Evaluate("(c+b)*a", a: 6, b: 4.5, c: 2.6);
    

        8
  •  0
  •   Jeremy Lakeman    6 年前

        string finalSource = ...;
        IEnumerable<Assembly> references = ...;
    
        var compilation = CSharpCompilation.Create("Dynamic",
            new[] { 
                SyntaxFactory.ParseSyntaxTree(
                    finalSource,
                    CSharpParseOptions.Default
                        .WithLanguageVersion(LanguageVersion.Latest)
                ) },
            references.Select(a => MetadataReference.CreateFromFile(a.Location)),
    
            new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default)
        );
    
        using var ms = new MemoryStream();
        var e = compilation.Emit(ms);
        if (!e.Success)
            throw new Exception("Compilation failed");
        ms.Seek(0, SeekOrigin.Begin);
    
        var context = new AssemblyLoadContext(null, true);
        var assembly = context.LoadFromStream(ms);
    

        AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetName().Name == "netstandard").Single(),
        typeof(object).Assembly
    
    推荐文章