mathematical-expression 实现 数学表达式解析 Java 篇
Java技术栏
使用 ME( mathematical-expression)数学表达式解析库 实现Java中 数学表达式 的解析和计算。
目录
文章目录
- mathematical-expression 实现 数学表达式解析 Java 篇
- 目录
- mathematical-expression 介绍
- 获取到 ME 组件
- Maven依赖坐标
- Gradle 依赖坐标
- ME 组件存储库
- ME 组件结构
- 无括号数学表达式计算组件
- 有括号的数学表达式计算
- 比较运算表达式
- 函数计算表达式
- 多参函数计算组件
- 高阶操作
- 数学方式的函数注册与计算
- 匿名实现的函数注册于计算
mathematical-expression 介绍
在计算机中,本身并不存在数学表达式的概念,数学表达式其本身是在人类世界中对于逻辑的一种总结规范,计算机并不了解这些公式中的符号,因此对于数学表达式也需要一个编译器,就像编程语言到机器码之间的编译器一样,mathematical-expression 是一种针对数学公式解析的有效工具,能够解析包含嵌套函数,包含函数,数列步长累加等数学公式,返回值是一个数值的结果对象,同时也可以进行比较运算的操作,再进行比较的时候,返回值是一个布尔值结果对象。
获取到 ME 组件
ME 组件的获取有诸多方式,接下来您可以根据需求选择您需要的方式来实现 ME 组件的获取与装载。
PS 请尽量使用 1.3.1 版本以及以上的版本,这将有助于您使用更加稳定的版本,修复了 1.2.x 版本中所有已知的bug
Maven依赖坐标
您可以直接使用maven将本框架导入到项目中使用,能够高效的使用该功能
<dependencies><dependency><groupId>io.github.BeardedManZhao</groupId><artifactId>mathematical-expression</artifactId><version>1.3.1</version></dependency>
</dependencies>
Gradle 依赖坐标
您也可以直接通过gradle将“mathematical-expression”载入到您的框架中,使用下面的依赖即可。
dependencies {implementation 'io.github.BeardedManZhao:mathematical-expression:1.3.1'
}
ME 组件存储库
您还可以在 ME 组件存储库 历史存档馆 中获取到您需要的版本对应的所有资源。
ME 组件结构
ME 组件主要由三个部分组成,分别是数据存储对象,以及,解析与计算对象,还有计算管理者,他们分别负责不同的任务和位置,共同配合,实现强大的计算操作。
接下来我们将进行实际的演示,讲述如何在 Java 中快速且方便的处理数学表达式。
无括号数学表达式计算组件
此组件顾名思义,就是用于没有括号的数学表达式的解析和计算中,此计算组件是所有计算组件的祖先,具有更简单的结构以及计算性能
但面对复杂的计算表达式,此计算组件将无法体现出其灵活性,下面是有关该表达式的一个操作示例。
public class MAIN {public static void main(String[] args) {// 准备一个数学表达式String s1 = "1 + 20 * 2 + 4";// 获取到无括号数学表达式final Calculation instance = Mathematical_Expression.getInstance(Mathematical_Expression.prefixExpressionOperation);// 开始进行检查try {instance.check(s1);// 如果没有异常就直接进行计算final CalculationNumberResults calculation = (CalculationNumberResults) instance.calculation(s1);// 打印结果System.out.println(calculation.getResult());} catch (WrongFormat e) {System.out.println("表达式错误,原因: " + e);}}
}
最终计算结果
45.0进程已结束,退出代码0
有括号的数学表达式计算
带有括号的数学计算表达式,是最常用的一种计算组件,其能够实现有效的数学表达式优先级计算操作,计算的复杂度也不会太高,下面就是结果
在库中诸多的计算组件都是基于此组件进行拓展的,下面就是一个使用示例。
public class MAIN {public static void main(String[] args) {// 准备一个数学表达式String s1 = "1 + 20 * (2 + 4)";// 获取到有括号数学表达式final Calculation instance = Mathematical_Expression.getInstance(Mathematical_Expression.bracketsCalculation2);// 开始进行检查try {instance.check(s1);// 如果没有异常就直接进行计算final CalculationNumberResults calculation = (CalculationNumberResults) instance.calculation(s1);// 打印结果System.out.println(calculation.getResult());} catch (WrongFormat e) {System.out.println("表达式错误,原因: " + e);}}
}
最终计算结果
121.0进程已结束,退出代码0
比较运算表达式
基于 有括号 计算组件的一种拓展,在这里我们可以针对两个数学表达式进行比较,在这里的比较操作中,能够实现有效的比较运算,返回值是 布尔 类型的结果对象,它的计算过程如下所示。
public class MAIN {public static void main(String[] args) throws WrongFormat {// 获取一个计算数学比较表达式的组件final Calculation instance = Mathematical_Expression.getInstance(Mathematical_Expression.booleanCalculation2);// 创建3个表达式String s1 = "1 + 2 + 4 * (10 - 3)";String s2 = "2 + 30 + (2 * 3) - 1";String s3 = "1 + 3 * 10";extracted(instance, s1 + " > " + s2);// false extracted(instance, s1 + " < " + s2);// true extracted(instance, s1 + " = " + s3);// true extracted(instance, s1 + " == " + s3);// true extracted(instance, s1 + " != " + s3);// false extracted(instance, s1 + " <> " + s3);// false extracted(instance, s1 + " <= " + s3);// true extracted(instance, s1 + " >= " + s3);// true extracted(instance, s1 + " != " + s2);// true extracted(instance, s1 + " <> " + s2);// true }private static void extracted(Calculation booleanCalculation2, String s) throws WrongFormat {// 检查表达式是否有错误booleanCalculation2.check(s);// 开始计算结果CalculationBooleanResults calculation = (CalculationBooleanResults) booleanCalculation2.calculation(s);// 打印结果数值System.out.println("计算层数:" + calculation.getResultLayers() + "\t计算结果:" + calculation.getResult() +"\t计算来源:" + calculation.getCalculationSourceName());}
}
下面就是计算结果,可以看到这里返回的结果是一个 布尔 类型的结果对象
计算层数:4 计算结果:false 计算来源:booleanCalculation2
计算层数:4 计算结果:true 计算来源:booleanCalculation2
计算层数:3 计算结果:true 计算来源:booleanCalculation2
计算层数:3 计算结果:true 计算来源:booleanCalculation2
计算层数:3 计算结果:false 计算来源:booleanCalculation2
计算层数:3 计算结果:false 计算来源:booleanCalculation2
计算层数:3 计算结果:true 计算来源:booleanCalculation2
计算层数:3 计算结果:true 计算来源:booleanCalculation2
计算层数:4 计算结果:true 计算来源:booleanCalculation2
计算层数:4 计算结果:true 计算来源:booleanCalculation2进程已结束,退出代码0
函数计算表达式
在 ME 库中,允许使用一些函数来进行计算操作,数学表达式中的函数在这里也可以实现,通过自定义实现函数的方式,能够封装计算逻辑,且有效的提升灵活性,其计算复杂度并不高,也是比较常用的计算组件。
接下来就是相关的使用演示!!!
public class MAIN {public static void main(String[] args) throws WrongFormat {// 实例化一个函数 名为DoubleValue 用于将一个数值乘2ManyToOneNumberFunction myFunction = new ManyToOneNumberFunction("DoubleValue") {@Overridepublic double run(double... numbers) {// 在这里的参数中,第一个参数就是被FunctionFormulaCalculation所传入的参数return numbers[0] * 2;}};// 将函数注册到管理者中CalculationManagement.register(myFunction);// 获取一个计算累加数学表达式的组件FunctionFormulaCalculation functionFormulaCalculation = FunctionFormulaCalculation.getInstance("zhao");// 构建一个数学表达式,表达式中使用到了函数 DoubleValueString s = "2 * DoubleValue(2 + 3) + 1";// 检查数学表达式functionFormulaCalculation.check(s);// 计算结果CalculationNumberResults calculation = functionFormulaCalculation.calculation(s);System.out.println("计算层数:"+calculation.getResultLayers()+"\t计算结果:"+calculation.getResult()+"\t计算来源:"+calculation.getCalculationSourceName());}
}
在这里就是相关的计算结果
计算层数:1 计算结果:21.0 计算来源:BracketsCalculation2进程已结束,退出代码0
多参函数计算组件
从 ME 库 1.1 版本开始 针对函数数学表达式的计算将不再限制于只能传递一个参数,而是可以传递无数个参数,每个参数会在函数中以函数形参的格式进入到函数对象并进行计算,接下来就是相关的实际演示。
public class MAIN {public static void main(String[] args) throws WrongFormat {// 实现一个sum函数 用于将数值求和ManyToOneNumberFunction manyToOneNumberFunction = new ManyToOneNumberFunction("sum") {@Overridepublic double run(double... numbers) {double res = 0;for (double number : numbers) {res += number;}System.out.println("调用函数 sum(" + Arrays.toString(numbers) + ") = " + res);return res;}};// 将该函数注册到管理者CalculationManagement.register(manyToOneNumberFunction);// 获取到新版本中的多参数学表达式解析组件Calculation functionFormulaCalculation = Mathematical_Expression.getInstance(Mathematical_Expression.functionFormulaCalculation2);// 构建一个数学表达式,表达式中使用到了函数 sumString s = "2 * sum(2 + 3, 1 + 20, 10 + (1 - 2)) + 1";// 检查数学表达式functionFormulaCalculation.check(s);// 计算结果CalculationNumberResults calculation = (CalculationNumberResults) functionFormulaCalculation.calculation(s);System.out.println("计算层数:"+calculation.getResultLayers()+"\t计算结果:"+calculation.getResult()+"\t计算来源:"+calculation.getCalculationSourceName());}
}
在这里就是相关的计算结果
调用函数 sum([5.0, 21.0, 9.0]) = 35.0
计算层数:1 计算结果:71.0 计算来源:BracketsCalculation2进程已结束,退出代码0
高阶操作
数学方式的函数注册与计算
package top.lingyuzhao;import core.Mathematical_Expression;
import core.calculation.Calculation;
import core.calculation.function.FunctionPackage;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 将 f 函数注册进来Mathematical_Expression.register_function("f(x) = x * x");// 准备要计算的表达式final String data = "1 + f(20) + 3";// 获取到计算组件final Calculation instance = Mathematical_Expression.getInstance(Mathematical_Expression.functionFormulaCalculation2);// 检查与计算instance.check(data);System.out.println(instance.calculation(data));}
}
下面就是计算结果
CalculationNumberResults{result=404.0, source='BracketsCalculation2'}
匿名实现的函数注册于计算
package top.lingyuzhao;import core.Mathematical_Expression;
import core.calculation.Calculation;
import core.calculation.function.FunctionPackage;
import core.calculation.function.ManyToOneNumberFunction;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 将 f 函数注册进来Mathematical_Expression.register_function(new ManyToOneNumberFunction("f") {@Overridepublic double run(double... numbers) {return 1 + numbers[0] * numbers[0] + 3;}});// 准备要计算的表达式final String data = "1 + f(20) + 3";// 获取到计算组件final Calculation instance = Mathematical_Expression.getInstance(Mathematical_Expression.functionFormulaCalculation2);// 检查与计算instance.check(data);System.out.println(instance.calculation(data));}
}
下面就是计算结果
CalculationNumberResults{result=408.0, source='BracketsCalculation2'}
- 相关文章
《mathematical-expression 实现 数学表达式解析 C++ 篇》
《公共API-数学表达式计算:mathematical-expression-JS篇》