mathematical-expression 实现 数学表达式解析 Java 篇(最新版本)

在这里插入图片描述

mathematical-expression (MAE)

社区 qq 群

大家可以直接加入群聊,进入来咨询作者和交流哦!!

qq 群号:931546838

🫠 重要通知

✅【一般】 PS 请尽量使用 1.3.1 版本以及以上的版本,这将有助于您使用更加稳定的版本,修复了 1.2.x
所有已知的bug

⚠️【重要】 1.3.7
版本和 1.4.0 版本的内容几乎一致,主要的区别就是包模块的变更,
请注意,我们将在 1.4.0 版本以及之后的所有版本中
重构包名为 io.github.beardedManZhao.mathematicalExpression 这是为了避免在 Java 的诸多依赖中,包名出现冲突的情况~

为了避免小伙伴们担心由于包更新导致的兼容性问题,因此我们提供了 1.3.7版本,
您可以继续使用旧包名,但是我们强烈建议您使用新版本,因为新版本的包名已经更新为 io.github.beardedManZhao.mathematicalExpression
若您对于修改包名称和更新有什么问题或建议,请及时联系我们!!

介绍

本框架是一种针对数学公式解析的有效工具,能够解析包含嵌套函数,包含函数,数列步长累加等数学公式,返回值是一个数值的结果对象,同时也可以进行比较运算的操作,再进行比较的时候,返回值是一个布尔值结果对象。

  • Maven依赖坐标

    您可以直接使用maven将本框架导入到项目中使用,能够高效的使用该功能


<dependencies>
    <dependency>
        <groupId>io.github.BeardedManZhao</groupId>
        <artifactId>mathematical-expression</artifactId>
      <version>1.5.6</version>
    </dependency>
</dependencies>

您也可以直接通过gradle将“mathematical-expression”载入到您的框架中,使用下面的依赖即可。

dependencies {
    implementation 'io.github.BeardedManZhao:mathematical-expression:1.5.6'
}

历史版本

您可以在 https://github.com/BeardedManZhao/mathematical-expression/tree/main/update 中查询到发布的所有版本的变更详细报告。

为什么要选择 mathematical-expression

mathematical-expression 具有简单,快速,易上手,支持的语言种类多 等优势,它具有 C Java python 版本的 API 使用方法几乎一致。

易于使用的API

调用库是很简单的,您可以使用如下代码进行计算,当然,如果您不需要进行检查,您还可以将下面的计算代码压缩为 System.out.println(Mathematical_Expression.getInstance(Mathematical_Expression.bracketsCalculation2).calculation("(1+2)*3"));
能够有效减少代码量!

import io.github.beardedManZhao.mathematicalExpression.core.Mathematical_Expression;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.Calculation;
import io.github.beardedManZhao.mathematicalExpression.exceptional.WrongFormat;

public class MAIN {
   
   

  public static void main(String[] args) throws WrongFormat {
   
   
    final Calculation instance = Mathematical_Expression.getInstance(
            // 在这里选择您要使用的不同计算组件即可
            Mathematical_Expression.bracketsCalculation2
    );
    // 如果您确保表达式的无误,可以不检查
    instance.check("(1+2)*3");
    System.out.println(instance.calculation("(1+2)*3"));
  }
}

超强的功能性,拿捏诸多函数 和 计算符

您不熟悉编程?很简单,您完全可以使用数学表达式进行函数的自定义,同时我们还准备了诸多的内置函数,它们统一在 function.calculation.io.github.beardedManZhao.mathematicalExpression.core.FunctionPackage
类中!!

import io.github.beardedManZhao.mathematicalExpression.core.Mathematical_Expression;

import io.github.beardedManZhao.mathematicalExpression.core.calculation.Calculation;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.function.FunctionPackage;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.function.Functions;
import io.github.beardedManZhao.mathematicalExpression.core.container.CalculationResults;
import io.github.beardedManZhao.mathematicalExpression.exceptional.WrongFormat;

// 准备一个数学函数 x 的阶乘 + 1
@Functions("f(x) = x! + 1")
public class MAIN {
   
   
    public static void main(String[] args) throws WrongFormat {
   
   
        // 您可以将我们内置的函数进行导入,这样就可以使用一些内置函数了,如 sum
        // 注册内置的函数库 - 数学库
        Mathematical_Expression.register_function(FunctionPackage.MATH);
        // 当然 您还可以使用自定义函数的方式 将您自己的函数 注册进去
        Mathematical_Expression.register_function("fTwo(x, y) = x + y");
        // 您也可以使用注解批量的 将 MAIN 注解的所有函数注册 并进行使用
        Mathematical_Expression.register_function(MAIN.class);
        // 在下面就可以开始进行计算了 首先是获取到计算组件
        final Calculation instance = Mathematical_Expression.getInstance(Mathematical_Expression.functionFormulaCalculation2);
        // 然后进行一个简单的检查
        instance.check("1 + sum(1,2,3,4) + f(3) * fTwo(1, 2)");
        // 然后直接进行计算 您的表达式中完全是可以使用函数的哦~~~
        final CalculationResults calculation = instance.calculation("1 + sum(1,2,3,4) + f(3) * fTwo(1, 2)");
        // 直接打印就可以啦~
        System.out.println(calculation);
    }
}

计算符号的支持不够多?不用担心,此库支持的运算符种类繁多,您可以在这里看到所有计算符.

符号名称 符号语法(n代表操作数) 支持版本 符号意义
加法运算符 n + n 1.0.0 将两个操作数进行相加运算
减法法运算符 n - n 1.0.0 将两个操作数进行相减运算
乘法运算符 n * n 1.0.0 将两个操作数进行相乘运算
除法运算符 n / n 1.0.0 将两个操作数进行相除运算
取余运算符 n % n 1.0.0 将两个操作数进行取余运算
阶乘运算符 n! 1.3.2 将操作数进行阶乘运算(Jvm组件暂不支持)
幂运算符 n ^ n 1.3.5 将操作数进行幂运算(Jvm组件暂不支持)

您还可以通过调整设置实现带有精度的计算操作以及缓存操作等!

import io.github.beardedManZhao.mathematicalExpression.core.Mathematical_Expression;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.Calculation;
import io.github.beardedManZhao.mathematicalExpression.core.container.CalculationResults;

import java.math.BigDecimal;

/**
 * This is the main entry point for the application, demonstrating mathematical expression parsing and evaluation.
 */
public class MAIN {
   
   
    public static void main(String[] args) {
   
   
        // Obtain an instance of the calculation component, which supports parentheses handling.
        final Calculation calculationInstance = Mathematical_Expression.getInstance(Mathematical_Expression.bracketsCalculation2);
        // Define a sample mathematical expression to evaluate.
        final String inputExpression = "0.3 * 3";
        // Enable caching to improve performance.
        Mathematical_Expression.Options.setUseCache(true);

        // Enable BigDecimal for more accurate results.
        Mathematical_Expression.Options.setUseBigDecimal(true);
        // Evaluate the expression and print the result.
        System.out.println(calculationInstance.calculation(inputExpression));

        // Disable BigDecimal for faster performance.
        Mathematical_Expression.Options.setUseBigDecimal(false);
        // Evaluate the expression and print the result.
        final CalculationResults calculation = calculationInstance.calculation(inputExpression);
        System.out.println(calculation);

        // Can extract different numerical objects
        System.out.println("Can extract different numerical objects!");
        final double result = (double) calculation.getResult();
        final BigDecimal bigDecimalResult = calculation.getBigDecimalResult();
        System.out.println(result);
        System.out.println(bigDecimalResult);
    }
}

种类繁多地计算组件

在mathematical-expression 中,我们提供了多种计算组件,您可以根据需要选择不同的计算组件,以实现不同的功能,同时还保持着相同的API调用方式。


import io.github.beardedManZhao.mathematicalExpression.core.Mathematical_Expression;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.Calculation;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.function.Functions;
import io.github.beardedManZhao.mathematicalExpression.exceptional.WrongFormat;

// 准备一个数学函数 x 的阶乘 + 1
@Functions("f(x) = x! + 1")
public class MAIN {
   
   
    public static void main(String[] args) throws WrongFormat {
   
   
        // 将 MAIN 注解的函数注册 并进行使用
        Mathematical_Expression.register_function(MAIN.class);
        final Calculation instance = Mathematical_Expression.getInstance(
                // 在这里选择函数计算组件即可
                Mathematical_Expression.functionFormulaCalculation2
        );
        // 如果您确保表达式的无误,可以不检查
        instance.check("f(1 + 2) - 3");
        System.out.println(instance.calculation("f(1 + 2) - 3"));

        /*----------------------------------*/

        // 您还可以用快速计算组件计算区间 [1+2, 30] 之间的求和
        final Calculation instance1 = Mathematical_Expression.getInstance(
                // 在这里选择快速求和计算组件即可 API 和上面是一样的
                Mathematical_Expression.fastSumOfIntervalsBrackets
        );
        instance1.check("1 + 2, 30");
        System.out.println(instance1.calculation("1 + 2, 30"));
    }
}

超高的灵活度

在其中的任何步骤所需要的函数,计算好的任何对象,都可以被单独获取到进行您想要的操作。例如数学函数是一种复杂的对象,其编译成功之后,您可以直接获取到它的函数对象,并不仅仅局限于在
mathematical-expression 中使用!

import io.github.beardedManZhao.mathematicalExpression.core.Mathematical_Expression;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.function.Functions;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.function.ManyToOneNumberFunction;
import io.github.beardedManZhao.mathematicalExpression.exceptional.WrongFormat;

// 准备一个数学函数 x 的阶乘 + 1
@Functions("f(x) = x! + 1")
public class MAIN {
   
   
    public static void main(String[] args) throws WrongFormat {
   
   
        // 将 MAIN 注解的函数注册 并进行使用
        Mathematical_Expression.register_function(MAIN.class);
        // 提取出 f(x) = x! + 1 的函数对象 我们知道这个函数的名字就是 f
        final ManyToOneNumberFunction f = Mathematical_Expression.getFunction("f");
        // 单独使用 f 进行计算
        final double run = f.run(3);
        System.out.println(run);
    }
}

详细的执行记录

您在一些计算组件中,可以使用 explain 函数来进行表达式的计算,这个函数能够将计算组件的计算过程完整的绘制成为一个日志结果对象,日志结果对象可以被绘制成为一个图,下面是支持的组件以及使用示例。

计算组件名称 是否支持 explain 从何时开始支持 相关知识
io.github.beardedManZhao.mathematicalExpression.core.calculation.PrefixExpressionOperation yes v1.3.5 click this
io.github.beardedManZhao.mathematicalExpression.core.calculation.BracketsCalculation2 yes v1.3.5 click this
io.github.beardedManZhao.mathematicalExpression.core.calculation.CumulativeCalculation yes v1.3.6 click this
io.github.beardedManZhao.mathematicalExpression.core.calculation.FunctionFormulaCalculation2 yes v1.3.6 click this
io.github.beardedManZhao.mathematicalExpression.core.calculation.number.ComplexCalculation yes v1.4.5
引入流程图代码生成库

您只需要导入下面的依赖坐标就可以自动实现相关组件的导入。这个库将会帮助您将计算组件的计算过程绘制成一个流程图。

<!-- 若您的 mathematicalExpression 版本大于 1.4.2 则不需要引入此依赖! -->
<dependency>
    <groupId>io.github.BeardedManZhao</groupId>
    <artifactId>varFormatter</artifactId>
    <version>1.0.4</version>
</dependency>
开始进行生成

导入了库之后,我们就可以像下面一样进行生成流程图。


import io.github.beardedManZhao.mathematicalExpression.core.Mathematical_Expression;
import io.github.beardedManZhao.mathematicalExpression.core.calculation.Calculation;
import io.github.beardedManZhao.mathematicalExpression.core.container.LogResults;
import io.github.beardedManZhao.mathematicalExpression.exceptional.WrongFormat;
import top.lingyuzhao.varFormatter.core.VarFormatter;

public class MAIN {
   
   
  public static void main(String[] args) throws WrongFormat {
   
   
    // 获取到一个有括号计算组件 您可以根据需求更换组件
    final Calculation instance = Mathematical_Expression.getInstance(Mathematical_Expression.bracketsCalculation2);
    // 然后进行一个简单的检查 这里我们要查询 1 + 2 ^ 4 - 2 * 3 + 2 的执行过程
    final String s = "1 + 2 ^ (2 + (10 - 7)) * 3 + 2";
    instance.check(s);
    // 我们可以通过 explain 获取到执行过程 它会返回一个对象 这个对象中有一个 result 字段 这个字段就是计算出来的结果
    final LogResults explain = instance.explain(s, true);
    System.out.println("计算结果:" + explain.getResult());
    // 事实上 LogResults 更大的作用是进行执行过程可视化 下面就是一个例子
    // 设置输出图的时候不拼接名字,因为在这里有很多的变量 需要进行关联的!拼接名字就不好关联了
    explain.setNameJoin(false);
    // 通过我们引入的 VarFormatter 可以很方便地进行格式化 我们在这里格式化为 MERMAID 图 代码
    System.out.println("graph LR");
    System.out.println(VarFormatter.MERMAID.getFormatter(true).format(explain));
  }
}

程序运行之后的结果如下所示

计算结果:99.0
graph LR
f_-1523352178("1 + 2 ^ (2 + (10 - 7)) * 3 + 2")
f_-1523352178==Map>Map==>f_1563255009
f_1563255009("2 + (10 - 7)")
f_1563255009==Map>Map==>f_1448155011
f_1448155011("10 - 7")
f_1448155011==Map>Map==>f_1507337
f_1507337("10-7+0")
f_1507337==Map>Map==>f_1507337_优先

f_1507337_优先==Map>Map==>f_1571371271_计算
f_1571371271("10.0 - 7.0")
f_1571371271_计算==Map>String/Number==>f_1571371271
f_1571371271--Map>value-->f_1571371271v{"3.0"}
f_1571371271_计算==Map>Map==>f_1507337_最终

f_1507337_最终==Map>Map==>f_1481348562_计算
f_1481348562("3.0 + 0.0")
f_1481348562_计算==Map>String/Number==>f_1481348562
f_1481348562--Map>value-->f_1481348562v{"3.0"}
f_1563255009==Map>Map==>f_47507548
f_47507548("2+3.0+0")
f_47507548==Map>Map==>f_47507548_优先

f_47507548_优先==Map>Map==>f_-1006161388_计算
f_-1006161388("2.0 + 3.0")
f_-1006161388_计算==Map>String/Number==>f_-1006161388
f_-1006161388--Map>value-->f_-1006161388v{"5.0"}
f_-1006161388_计算==Map>Map==>f_47507548_最终

f_47507548_最终==Map>Map==>f_-2133560364_计算
f_-2133560364("5.0 + 0.0")
f_-2133560364_计算==Map>String/Number==>f_-2133560364
f_-2133560364--Map>value-->f_-2133560364v{"5.0"}
f_-1523352178==Map>Map==>f_-418786079
f_-418786079("1+2^5.0*3+2+0")
f_-418786079==Map>Map==>f_-418786079_优先

f_-418786079_优先==Map>Map==>f_-959059895_计算
f_-959059895("2.0 ^ 5.0")
f_-959059895_计算==Map>String/Number==>f_-959059895
f_-959059895--Map>value-->f_-959059895v{"32.0"}
f_-959059895_计算==Map>Map==>f_1855628224_计算
f_1855628224("32.0 * 3.0")
f_1855628224_计算==Map>String/Number==>f_1855628224
f_1855628224--Map>value-->f_1855628224v{"96.0"}
f_1855628224_计算==Map>Map==>f_2037586494_计算
f_2037586494("96.0 + 2.0")
f_2037586494_计算==Map>String/Number==>f_2037586494
f_2037586494--Map>value-->f_2037586494v{"98.0"}
f_2037586494_计算==Map>Map==>f_-418786079_最终

f_-418786079_最终==Map>Map==>f_-929530109_计算
f_-929530109("1.0 + 98.0")
f_-929530109_计算==Map>String/Number==>f_-929530109
f_-929530109--Map>value-->f_-929530109v{"99.0"}
f_-929530109_计算==Map>String/Number==>result
result--Map>value-->resultv{"99.0"}


进程已结束,退出代码为 0

程序运行之后的结果中有 mermaid 的图代码,我们在下面将其展示了出来 供大家观看!

1.4.6 版本之后,explain

的可视化效果进行了优化,这里展示的是新版可视化的效果,您可以在 更新记录中查看到相关说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值