• 【awesome-dotnet-core-learning】(2)-Sprache.Calc-表达式计算器


    【awesome-dotnet-core-learning】(2)-Sprache.Calc-表达式计算器

    示例代码托管在GITHUB上, 欢迎STAR!

    严格来说, Sprache.Calc只是上一篇Sprache-解析器构建库中介绍的Sprache的一个扩展库,而且未罗列在awesome-dotnet-core中.但是表达式计算在很多应用中都有需求,所以单独写一篇博客介绍它.

    简介

    Sprache.Calc提供了简单易用的表达式计算器功能.可将输入的字符串做为一个表达式,转换成结构化的LINQ表达式,并且可被编译为可执行的委托.

    特点

    • 支持算术运算, 自定义函数和参数
    • 转换为LINQ表达式
    • 可编译成委托并执行
    • 因为可编译成委托,所以性能上与原生C#相同

    快速上手

    以下示例演示了用Sprache.Calc编写一个计算表达式的程序.并演示了自定义函数和参数的使用方法.

    1. 创建一个.NET Core的命令行应用程序(详细步骤略)

    2. 使用Nuget安装Sprache.Calc:

      Install-Package Sprache.Calc
      
    3. Program.cs中,首先创建一个表达式计算器:

      private static readonly XtensibleCalculator Calculator = new XtensibleCalculator();
      
    4. 编写一个辅助方法,用于编译,执行输入的文本,并输出结果

      /// <summary>
      /// 运行表达式,输出计算结果
      /// </summary>
      /// <param name="text">文本</param>
      /// <param name="parameters">参数</param>
      private static void RunExpression(string text, params Expression<Func<double, double>>[] parameters)
      {
          var expr = Calculator.ParseExpression(text, parameters);
          var func = expr.Compile();
          Console.WriteLine($"{text} = {func()}");
      }
      

      首先使用XtensibleCalculator的ParseExpression方法解析文本表达式, 该方法返回值为Expression<Func<double>>类型.所以可以使用Compile方法继承编译为Func<double>, 最后直接执行即可得到计算结果.

      parameters用于接收表达式中的参数.每一个都是一个Func<double, double>类型委托,如没有参数,可不传递.

    5. Main方法中,就可调用RunExpression了,首先我们测试基本的四则运算:

      // 四则运算
      RunExpression("1 + 2 * 3");
      RunExpression("(1 + 2) * 3");
      

      输出结果:

      1 + 2 * 3 = 7
      (1 + 2) * 3 = 9
      

      可注意到运算符的优先级和括号都是支持的.

    6. 测试自定义函数:

      // 自定义函数
      // 这里注册了一个名为"阶乘"的函数,用来计算一个数的阶乘
      Calculator.RegisterFunction("阶乘", n =>
      {
          // n的阶乘 = n * (n-1) * (n-2) * ... * 1
          int r = 1;
          for (int i = (int) n; i > 0; i--) r *= i;
          return r;
      });
      RunExpression("阶乘(3) + 阶乘(4)");
      

      我们通过RegisterFunction方法注册了一个名为"阶乘"的函数(是的自定义函数名可以为中文),然后通过Lambda函数提供了计算逻辑.这样在表达式中就可以使用我们的自定义函数了.

      输出结果:

      阶乘(3) + 阶乘(4) = 30
      
    7. 测试参数

      // 参数
      RunExpression("阶乘(a) + 阶乘(b)", a => 4, b => 5); // 将4代入a, 5代入b
      

      我们将表达式中的参数,通过lambda表达式赋值,这样在运行时,该参数的值就会参与计算了.

      输出结果:

      阶乘(a) + 阶乘(b) = 144
      

    类似库

  • 相关阅读:
    1.33 (累积互素数)
    1.33 (过滤累积和 求区间内所有素数之和)
    1.32 (更高层次的抽象! 乘法与加法本来就是一回事)
    1.31 (另一种求圆周率的算法)
    1.30 (递归的sum变迭代)
    习题1.29 (积分方法的优化---simpson规则)
    1.3.1 (对过程的抽象)
    SICP习题 1.23(素数查找的去偶数优化)
    SICP习题 1.22(素数)
    pom.xml
  • 原文地址:https://www.cnblogs.com/waku/p/10510464.html
Copyright © 2020-2023  润新知