mathematical-expression(MAE)数学表达式 数学函数 解析编译库,有效的快速和简单易用的数学和计算机的编译器

image 数学表达式

  • Switch to English Document

介绍

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

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

  • Maven依赖坐标

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


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

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

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

为什么要选择 mathematical-expression

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

易于使用的API

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

import core.Mathematical_Expression;
import core.calculation.Calculation;
import 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"));}
}

种类繁多的计算组件

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

package utils;import core.Mathematical_Expression;
import core.calculation.Calculation;
import core.calculation.function.Functions;
import 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 core.Mathematical_Expression;
import core.calculation.function.Functions;
import core.calculation.function.ManyToOneNumberFunction;
import 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 的函数对象 我们知道这个函数的名字就是 ffinal ManyToOneNumberFunction f = Mathematical_Expression.getFunction("f");// 单独使用 f 进行计算final double run = f.run(3);System.out.println(run);}
}

框架架构

通过 mathematical-expression 库直接获取到计算组件并进行计算

package utils;import core.Mathematical_Expression;
import core.calculation.number.NumberCalculation;
import core.container.CalculationNumberResults;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 构建需要计算的两种表达式String s1 = "1 + 20 - 2 + 4", s2 = "1 + 20 - (2 + 4)";// 通过库获取到计算无括号表达式的计算组件NumberCalculation prefixExpressionOperation = Mathematical_Expression.getInstance(Mathematical_Expression.prefixExpressionOperation, "prefixExpressionOperation");// 通过库获取到计算有括号表达式的计算组件NumberCalculation bracketsCalculation2 = Mathematical_Expression.getInstance(Mathematical_Expression.bracketsCalculation2, "bracketsCalculation2");// 将第一个公式传递给无括号表达式的计算组件prefixExpressionOperation.check(s1);CalculationNumberResults calculation1 = prefixExpressionOperation.calculation(s1);// 打印出第一个表达式的计算结果System.out.println("计算层数:" + calculation1.getResultLayers() + "\n计算结果:" + calculation1.getResult() +"\n计算来源:" + calculation1.getCalculationSourceName());// 将第二个公式传递给无括号表达式的计算组件bracketsCalculation2.check(s2);CalculationNumberResults calculation2 = bracketsCalculation2.calculation(s2);// 打印出第二个表达式的计算结果System.out.println("计算层数:" + calculation2.getResultLayers() + "\n计算结果:" + calculation2.getResult() +"\n计算来源:" + calculation2.getCalculationSourceName());}
}
  • 运行结果

    通过导入包可以获取到各个计算组件的模块对象,能够有效的减少代码导包代码。

计算层数:1
计算结果:23.0
计算来源:prefixExpressionOperation
计算层数:2
计算结果:15.0
计算来源:bracketsCalculation2

计算管理者

  • 类组件:core.manager.CalculationManagement

  • 介绍:

    管理者是一个为了同时使用单例与动态对象而设计的一个组件,管理者的存在可以使得每一个组件能够被名字所获取到,相同名字的组件,在内存中的存储地址也是一样的,避免了冗余组件的调用,同时针对需要使用到动态成员的组件,也可以通过一个新名字获取到一个新组件。

  • API使用示例

package utils;import core.calculation.number.FunctionFormulaCalculation;
import core.calculation.number.PrefixExpressionOperation;
import core.manager.CalculationManagement;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) {// 实例化三个计算组件// TODO getInstance会自动从管理者中获取,如果没有获取到,就会创建并注册然后再返回数据 这个方法即可以创建也可以访问管理者PrefixExpressionOperation a = PrefixExpressionOperation.getInstance("a");FunctionFormulaCalculation b = FunctionFormulaCalculation.getInstance("b");PrefixExpressionOperation a1 = PrefixExpressionOperation.getInstance("a1");// 注册一个名为“a”的无括号解析组件CalculationManagement.register(a);// 注册一个名为“b”的函数解析组件CalculationManagement.register(b);// 注册一个名为“a1”的无括号解析组件CalculationManagement.register(a1);// 打印我们示例化的 与 从管理者获取到的组件的内存数据是否一致System.err.println(a + "  " + CalculationManagement.getCalculationByName("a"));System.err.println(b + "  " + CalculationManagement.getCalculationByName("b"));System.err.println(a1 + "  " + CalculationManagement.getCalculationByName("a1"));}
}
  • 运行结果

    最后三行就是内存数据的比较,实例化出来的组件与管理者中的组件在内存中是一样的,但是不同名称的组件是不同的。

[INFO][Calculation Management][22-11-14:11]] : +============================== Welcome to [mathematical expression] ==============================+
[INFO][Calculation Management][22-11-14:11]] : + 	Start time Mon Nov 14 11:45:13 CST 2022
[INFO][Calculation Management][22-11-14:11]] : + 	Calculation component manager initialized successfully
[INFO][Calculation Management][22-11-14:11]] : + 	For more information, see: https://github.com/BeardedManZhao/mathematical-expression.git
[INFO][Calculation Management][22-11-14:11]] : +--------------------------------------------------------------------------------------------------+
[INFO][Calculation Management][22-11-14:11]] : A computing component is registered a
[INFO][Calculation Management][22-11-14:11]] : A computing component is registered PrefixExpressionOperation
[INFO][Calculation Management][22-11-14:11]] : A computing component is registered BracketsCalculation2
[INFO][Calculation Management][22-11-14:11]] : A computing component is registered b
[INFO][Calculation Management][22-11-14:11]] : A computing component is registered a1
[INFO][Calculation Management][22-11-14:11]] : A computing component is registered a
[INFO][Calculation Management][22-11-14:11]] : A computing component is registered b
[INFO][Calculation Management][22-11-14:11]] : A computing component is registered a1
[INFO][Calculation Management][22-11-14:11]] : Get the [a] component from the manager
[INFO][Calculation Management][22-11-14:11]] : Get the [b] component from the manager
[INFO][Calculation Management][22-11-14:11]] : Get the [a1] component from the manager
core.calculation.number.PrefixExpressionOperation@8ad73b  core.calculation.number.PrefixExpressionOperation@8ad73b
core.calculation.number.FunctionFormulaCalculation@762604  core.calculation.number.FunctionFormulaCalculation@762604
core.calculation.number.PrefixExpressionOperation@41e737  core.calculation.number.PrefixExpressionOperation@41e737

计算组件介绍

无括号表达式

  • 类组件:core.calculation.number.PrefixExpressionOperation

  • 介绍

    针对一个没有括号,但是有加减乘除以及取余等运算操作的数学表达式而设计的组件,该组件可以实现带有优先级计算的功能,其中通过前缀表达式解析计算,将操作数与操作符一同存储到栈,在存储的同时配有计算优先级比较,如果当下的优先级较小,就先将上一个操作数与操作符与当前操作数进行运算,形成一个新的数值,然后再入栈。

  • API使用示例

    该组件支持的运算符有: a+b a-b a*b a/b a%b

import core.calculation.number.PrefixExpressionOperation;
import core.container.CalculationNumberResults;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 获取一个计算无括号表达式的函数PrefixExpressionOperation prefixExpressionOperation = PrefixExpressionOperation.getInstance("p");// 创建一个表达式String s = "1 + 2 + 4 * 10 - 3";// 检查表达式是否有错误prefixExpressionOperation.check(s);// 开始计算结果CalculationNumberResults calculation = prefixExpressionOperation.calculation(s);// 打印结果数值System.out.println("计算层数:" + calculation.getResultLayers() + "\n计算结果:" + calculation.getResult() +"\n计算来源:" + calculation.getCalculationSourceName());}
}
  • 运行结果

    在API调用中,对函数的运行结果进行了打印,可以看到,组件计算的返回值是一个结果集对象,在该对象中存储的就是很多有关计算结果相关的信息。

计算层数:2
计算结果:40.0
计算来源:p

嵌套括号表达式

  • 类组件:core.calculation.number.BracketsCalculation2

  • 介绍:

    嵌套括号表达式解析组件,能够针对带有多个括号的数学表达式进行解析与结果计算,针对嵌套括号进行优先级的解析与计算,该组件依赖于“core.calculation.number.PrefixExpressionOperation”,在该组件中采用递归进行括号的解析,然后将最内层面的表达式提供给“core.calculation.number.PrefixExpressionOperation”进行计算。

  • API使用示例

    该组件支持的运算符有: a+b a-b a*b a/b a%b ( )

package utils;import core.calculation.number.BracketsCalculation2;
import core.container.CalculationNumberResults;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 获取一个计算无括号表达式的函数BracketsCalculation2 bracketsCalculation = BracketsCalculation2.getInstance("BracketsCalculation");// 创建一个表达式String s = "1 + 2 + 4 * (10 - 3)";// 检查表达式是否有错误bracketsCalculation.check(s);// 开始计算结果CalculationNumberResults calculation = bracketsCalculation.calculation(s);// 打印结果数值System.out.println("计算层数:" + calculation.getResultLayers() + "\n计算结果:" + calculation.getResult() +"\n计算来源:" + calculation.getCalculationSourceName());}
}
  • 运行结果

    在API调用中,对表达式的计算结果进行了打印,可以看到,组件计算的返回值是一个数值结果对象,在该对象中存储的就是很多有关计算结果相关的信息。

计算层数:2
计算结果:31.0
计算来源:BracketsCalculation

数学比较表达式

  • 类组件:core.calculation.bool.BooleanCalculation2

  • 介绍

    使用比较运算符两个括号表达式是否相互成立的一个组件,返回值是一个布尔类型的结果对象,该组件能够比较两个数值的大小等,也可以比较两个表达式之间的大小等关系,依赖于组件“core.calculation.bool.BooleanCalculation2”

  • API使用示例

    该组件支持的运算符如API中演示

package utils;import core.calculation.bool.BooleanCalculation2;
import core.container.CalculationBooleanResults;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 获取一个计算数学比较表达式的组件BooleanCalculation2 booleanCalculation2 = BooleanCalculation2.getInstance("Bool");// 创建3个表达式String s1 = "1 + 2 + 4 * (10 - 3)";String s2 = "2 + 30 + (2 * 3) - 1";String s3 = "1 + 3 * 10";extracted(booleanCalculation2, s1 + " > " + s2);// false	extracted(booleanCalculation2, s1 + " < " + s2);// true	extracted(booleanCalculation2, s1 + " = " + s3);// true	extracted(booleanCalculation2, s1 + " == " + s3);// true	extracted(booleanCalculation2, s1 + " != " + s3);// false	extracted(booleanCalculation2, s1 + " <> " + s3);// false	extracted(booleanCalculation2, s1 + " <= " + s3);// true	extracted(booleanCalculation2, s1 + " >= " + s3);// true	extracted(booleanCalculation2, s1 + " != " + s2);// true	extracted(booleanCalculation2, s1 + " <> " + s2);// true	}private static void extracted(BooleanCalculation2 booleanCalculation2, String s) throws WrongFormat {// 检查表达式是否有错误booleanCalculation2.check(s);// 开始计算结果CalculationBooleanResults calculation = booleanCalculation2.calculation(s);// 打印结果数值System.out.println("计算层数:" + calculation.getResultLayers() + "\t计算结果:" + calculation.getResult() +"\t计算来源:" + calculation.getCalculationSourceName());}
}
  • 运行结果
计算层数:4	计算结果:false	计算来源:Bool
计算层数:4	计算结果:true	计算来源:Bool
计算层数:3	计算结果:true	计算来源:Bool
计算层数:3	计算结果:true	计算来源:Bool
计算层数:3	计算结果:false	计算来源:Bool
计算层数:3	计算结果:false	计算来源:Bool
计算层数:3	计算结果:true	计算来源:Bool
计算层数:3	计算结果:true	计算来源:Bool
计算层数:4	计算结果:true	计算来源:Bool
计算层数:4	计算结果:true	计算来源:Bool

区间累加表达式

  • 类组件:core.calculation.number.CumulativeCalculation

  • 介绍

    在数学表达式中,往往有这样的一种公式,公式内容如下图所示,可以看到需要进行累加的数列操作,那么在这种公式的需求下,您可以通过上面的类组件去达到您所需要的目的。
    img_1

  • API使用示例

    语法层面于其他组件几乎一致,数学表达式的撰写于组件的计算示例就如下面所示,在这里展示的就是一个累加数学公式的计算。

package utils;import core.calculation.number.CumulativeCalculation;
import core.container.CalculationNumberResults;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 获取一个计算累加数学表达式的组件CumulativeCalculation cumulativeCalculation = CumulativeCalculation.getInstance("zhao");// 构建一个数学表达式,这里的"n[1,10,1]"就类似数学中的累加符号,n会在这个区间内不断增加,每增加一次都会被带入公式中计算一次// 其中[1,10,1]中的最后一个1 代表增加步长,能够实现区间内不同等差值的累加String s = "n[1,10,1] 2 * (n + 1)";// 检查数学表达式cumulativeCalculation.check(s);// 计算结果CalculationNumberResults calculation = cumulativeCalculation.calculation(s);System.out.println("计算层数:" + calculation.getResultLayers() + "\t计算结果:" + calculation.getResult() +"\t计算来源:" + calculation.getCalculationSourceName());}
}
  • 运行结果
计算层数:21	计算结果:130.0	计算来源:zhao

函数运算表达式

  • 类组件:core.calculation.number.FunctionFormulaCalculation

  • 介绍

    针对一些函数的操作,在该框架中也有支持,可以使用上面的类进行这中需要函数的数学表达式的书写,需要注意的是,一切在表达式中使用到的函数都需要在“CalculationManagement”中进行逻辑注册,使得计算的时候可以访问到函数

  • API使用示例

package utils;import core.calculation.function.ManyToOneNumberFunction;
import core.calculation.number.FunctionFormulaCalculation;
import core.container.CalculationNumberResults;
import core.manager.CalculationManagement;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 实例化一个函数 名为DoubleValue 用于将一个数值乘2ManyToOneNumberFunction myFunction = new ManyToOneNumberFunction("DoubleValue") {/*** 函数的运行逻辑实现** @param numbers 这里是函数的数据输入对象,由框架向这里传递数据输入参数* @return 这里是数据经过函数转换之后的数据*/@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());}
}
  • 运行结果
[INFO][zhao][22-11-14:11]] : Find and prepare the startup function: DoubleValue
计算层数:1	计算结果:21.0	计算来源:BracketsCalculation2

多参函数运算表达式

  • 类组件:core.calculation.number.FunctionFormulaCalculation2

  • 介绍

    针对一些在表达式中使用了函数的表达式计算,可以使用上面的类进行操作,它是“core.calculation.number.FunctionFormulaCalculation”类的升级版,从1.1版本开始出现,同时也是它的一个子类拓展实现。

    相较于父类,本组件弥补了父类只能解析带有一个参数函数表达式的不足,在该组件中,可以使用很多的实参进行函数的运算,例如sum(
    1,2,3)
    这类函数,就是一个多参函数,接下来请看API的使用示例,在此示例中,展示了多惨函数表达式的计算与结果。

package utils;import core.calculation.function.ManyToOneNumberFunction;
import core.calculation.number.FunctionFormulaCalculation2;
import core.container.CalculationNumberResults;
import core.manager.CalculationManagement;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 实现一个sum函数ManyToOneNumberFunction manyToOneNumberFunction = new ManyToOneNumberFunction("sum") {/*** 函数的运行逻辑实现** @param numbers 这里是函数的数据输入对象,由框架向这里传递数据输入参数* @return 这里是数据经过函数转换之后的数据*/@Overridepublic double run(double... numbers) {double res = 0;for (double number : numbers) {res += number;}return res;}};// 将该函数注册到管理者CalculationManagement.register(manyToOneNumberFunction);// 获取到新版本的函数计算组件FunctionFormulaCalculation2 functionFormulaCalculation2 = FunctionFormulaCalculation2.getInstance("zhao");// 构建我们需要计算的公式 TODO 在这个表达式中的函数sum形参,不只有1个,是多参的函数String s = "2 * (200 - sum(1 + 10.1, 2, 3)) + sum(10, 20)";// 启用共享池,能够加快计算的速度,计算的公式越复杂,该共享池的效果越显著functionFormulaCalculation2.setStartSharedPool(true);// 开始检查公式是否有错误functionFormulaCalculation2.check(s);// 获取到计算结果CalculationNumberResults calculation = functionFormulaCalculation2.calculation(s);System.out.println("计算层数:" + calculation.getResultLayers() + "\t计算结果:" + calculation.getResult() +"\t计算来源:" + calculation.getCalculationSourceName());}
}
  • 运行结果
计算层数:2	计算结果:397.8	计算来源:BracketsCalculation2
数学函数表达式注册

您可以直接使用一个函数的数学表达式来实现某个函数的注册,函数表达式的格式为 函数名字(参数1,参数2,参数3) = 函数逻辑表达式,例如 参数1 + 参数2
下面是一个注册示例

这样注册的函数 也是可以直接在数学表达式中使用的!

package utils;import core.Mathematical_Expression;
import core.manager.ConstantRegion;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {System.out.println(ConstantRegion.VERSION);// 开始进行注册 TODO 我们在这里注册了一个叫做 mySum 的函数 它接收两个参数 输出的是两个参数的求和结果if (Mathematical_Expression.register_function("mySum(a, b) = a + b")) {System.out.println("函数注册成功!");}}
}

快速区间求和计算组件(基于括号表达式)

  • 类组件:mathematical_expression/core/calculation/number/fastSumOfIntervalsBrackets.py

  • 介绍 1.15版本的新产物,区间快速求和组件,是针对一个等差为1的区间进行所有元素求和的快速组件,它将一个区间在逻辑上模拟成为一个数学数列,并通过求和公式进行快速的求和。

    该组件实现了共享池计算功能,将检查,计算,以及上一次结果记录实现,能够加快计算速度,具体API调用如下所示。

package utils;import core.calculation.number.FastSumOfIntervalsBrackets;
import core.container.CalculationNumberResults;
import exceptional.WrongFormat;public class MAIN {public static void main(String[] args) throws WrongFormat {// 获取到区间求和快计算组件FastSumOfIntervalsBrackets fast = FastSumOfIntervalsBrackets.getInstance("fast");// 构建一个需要计算的表达式 下面的表达式代表 从 11 = (1+10) 加到 13 = (20-(5+2)) 默认等差为2 结果应为 24String s = "1 + 10, 20 - (5 + 2)";// 检查表达式,共享池从1.2版本后,已经是默认启用的状态了!不需要手动设置了// fast.setStartSharedPool(true);fast.check(s);// 从1.2版本之后,累加组件支持设置步长参数,1.2.1版本中开始正式支持步长区间的求和fast.step = 2;// 开始计算CalculationNumberResults calculation = fast.calculation(s);// 打印计算结果System.out.println("计算层数:" + calculation.getResultLayers() + "\t计算结果:" + calculation.getResult() +"\t计算来源:" + calculation.getCalculationSourceName());}
}
  • 运行结果 从上面代码中我们可以看到,快速区间求和计算的公式由被逗号分割的两个括号表达式组成
计算层数:3	计算结果:24.0	计算来源:fast

快速区间累乘计算组件(基于括号表达式)

  • 类组件:core.calculation.number.FastMultiplyOfIntervalsBrackets

  • 介绍 1.2版本的新产物,区间快速累乘组件,是针对一个等差为n的区间进行所有元素累乘的快速组件,它将一个区间在逻辑上模拟成为一个数学数列,并通过求和公式进行快速的累乘。

    该组件实现了共享池计算功能,将检查,计算,以及上一次结果记录实现,能够加快计算速度,具体API调用如下所示。

package utils;import core.calculation.number.FastMultiplyOfIntervalsBrackets;
import core.container.CalculationNumberResults;
import exceptional.WrongFormat;/*** 测试用类*/
public class MAIN {public static void main(String[] args) throws WrongFormat {// 获取到区间求和快计算组件FastMultiplyOfIntervalsBrackets fast = FastMultiplyOfIntervalsBrackets.getInstance("fast");// 构建一个需要计算的表达式 下面的表达式代表 从 11 = (1+10) 乘到 13 = (20-(5+2)) 默认等差为2// 结果应为 11 * 13 = 143String s = "1 + 10, 20 - (5 + 2)";// 检查表达式,共享池从1.2版本后,已经是默认启用的状态了!不需要手动设置了// fast.setStartSharedPool(true);fast.check(s);// 从1.2版本之后,累加组件支持设置步长参数,1.2.1版本中开始正式支持步长区间的求和fast.step = 2;// 开始计算CalculationNumberResults calculation = fast.calculation(s);// 打印计算结果System.out.println("计算层数:" + calculation.getResultLayers() + "\t计算结果:" + calculation.getResult() +"\t计算来源:" + calculation.getCalculationSourceName());}
}
  • 运行结果

    从上面代码中我们可以看到,快速区间求和计算的公式由被逗号分割的两个括号表达式组成

计算层数:3	计算结果:143.0	计算来源:fast

高阶操作

数学方式的函数注册与计算

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 numbers[0] * numbers[0];}});// 准备要计算的表达式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 utils;import core.Mathematical_Expression;
import core.calculation.Calculation;
import core.calculation.function.Functions;
import exceptional.WrongFormat;@Functions({// 这里是需要被注册的两个函数 在这里标记一下"f(x) = x * x","ff(x) = f(x) + 1"
})
public class MAIN {public static void main(String[] args) throws WrongFormat {// 将 MAIN 类中标记的所有函数注册if (Mathematical_Expression.register_function(MAIN.class)) {// 构建需要计算的表达式final String string = "1 + ff(1 + 2) * 2";// 获取到函数计算组件Calculation calculation = Mathematical_Expression.getInstance(Mathematical_Expression.functionFormulaCalculation2);// 开始进行计算calculation.check(string);System.out.println(calculation.calculation(string));}}
}

下面就是计算结果

CalculationNumberResults{result=21.0, source='functionFormulaCalculation2'}

直接获取到函数对象 以及 将函数对象保存到文件

所有的函数对象都可以被提取出来,而针对“数学函数表达式”所注册的函数是可以被保存到文件中的,我们可以直接进行序列化的操作保存它,接下来我们将展示一些示例。

提取出函数对象 单独计算
package utils;import core.Mathematical_Expression;
import core.calculation.function.Functions;
import core.calculation.function.ManyToOneNumberFunction;
import exceptional.WrongFormat;import java.io.IOException;@Functions({// 这里是需要被注册的两个函数 在这里标记一下 分别是 f 和 ff 两个函数"f(x) = x * x","ff(x) = f(x) + 1"
})
public class MAIN {public static void main(String[] args) throws WrongFormat {// 将 MAIN 类中标记的所有函数注册if (Mathematical_Expression.register_function(MAIN.class)) {// 获取到 ff 函数final ManyToOneNumberFunction ff = Mathematical_Expression.getFunction("ff");// 计算出结果final double run = ff.run(1024);System.out.println(run);}}
}

下面就是计算结果

1048577.0
提取出函数对象 保存到文件

需要注意的是,如果您要保存的函数中使用到了其它函数,例如 ff(x) = f(x) + 1,那么您需要将 f(x) = x * x
也保存到文件中,在下面展示的是保存一个函数的代码。

package utils;import core.Mathematical_Expression;
import core.calculation.function.ExpressionFunction;
import core.calculation.function.Functions;
import core.calculation.function.ManyToOneNumberFunction;
import exceptional.WrongFormat;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;@Functions({// 这里是需要被注册的两个函数 在这里标记一下 分别是 f 和 ff 两个函数"f(x) = x * x","ff(x) = f(x) + 1"
})
public class MAIN {public static void main(String[] args) throws WrongFormat, IOException {// 将 MAIN 类中标记的所有函数注册if (Mathematical_Expression.register_function(MAIN.class)) {// 获取到 ff 函数final ManyToOneNumberFunction ff = Mathematical_Expression.getFunction("f");// 保存到文件 TODO ExpressionFunction 的函数是可以被保存到文件中的try (final ObjectOutputStream objectOutput = new ObjectOutputStream(Files.newOutputStream(Paths.get("C:\\Users\\zhao\\Desktop\\fsdownload\\f.me")))) {// 将 ff 保存到数据流中((ExpressionFunction) ff).saveTo(objectOutput);}}}
}

事实上,您还可以一次保存多个函数对象到一个文件中,这将会有助于帮助您解决函数依赖问题!

package utils;import core.Mathematical_Expression;
import core.calculation.function.ExpressionFunction;
import core.calculation.function.Functions;
import core.calculation.function.ManyToOneNumberFunction;
import exceptional.WrongFormat;import java.io.IOException;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;@Functions({// 这里是需要被注册的两个函数 在这里标记一下 分别是 f 和 ff 两个函数"f(x) = x * x","ff(x) = f(x) + 1"
})
public class MAIN {public static void main(String[] args) throws WrongFormat, IOException {// 将 MAIN 类中标记的所有函数注册if (Mathematical_Expression.register_function(MAIN.class)) {// 获取到 ff 函数 以及 f 函数final ManyToOneNumberFunction ff = Mathematical_Expression.getFunction("ff");final ManyToOneNumberFunction f = Mathematical_Expression.getFunction("f");// 保存到文件 TODO ExpressionFunction 的函数是可以被保存到文件中的try (final ObjectOutputStream objectOutput = new ObjectOutputStream(Files.newOutputStream(Paths.get("C:\\Users\\zhao\\Desktop\\fsdownload\\f.me")))) {// 将 ff 和 f 保存到数据流中((ExpressionFunction) ff).saveTo(objectOutput);((ExpressionFunction) f).saveTo(objectOutput);}}}
}

将文件保存的函数对象加载到库中

函数可以被序列化,当然也可以被反序列化,反序列化之后您可以将其注册到库中,也可以直接使用它!!!

package utils;import core.Mathematical_Expression;
import core.calculation.function.ExpressionFunction;
import core.calculation.function.ManyToOneNumberFunction;import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;public class MAIN {public static void main(String[] args) throws IOException {ManyToOneNumberFunction function;try (final ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(Paths.get("C:\\Users\\zhao\\Desktop\\fsdownload\\f.me")))) {// 在这里读取到函数对象function = ExpressionFunction.readFrom(objectInputStream);}// 把函数注册回 Mathematical_ExpressionMathematical_Expression.register_function(function);// 也可以直接使用它final double run = function.run(1024);System.out.println(run);}
}

当然,反序列化也支持多个函数对象的加载,下面是一个示例

package utils;import core.Mathematical_Expression;
import core.calculation.function.ExpressionFunction;
import core.calculation.function.ManyToOneNumberFunction;import java.io.IOException;
import java.io.ObjectInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;public class MAIN {public static void main(String[] args) throws IOException {ManyToOneNumberFunction ff, f;try (final ObjectInputStream objectInputStream = new ObjectInputStream(Files.newInputStream(Paths.get("C:\\Users\\zhao\\Desktop\\fsdownload\\f.me")))) {// 在这里读取到函数对象(要注意这里和保存时的顺序一致哦!!)// 如果要是不确定顺序,可以读取直接读取出来注册到库里 库会自动将函数的名称解析出来ff = ExpressionFunction.readFrom(objectInputStream);f = ExpressionFunction.readFrom(objectInputStream);}// 把函数注册回 Mathematical_ExpressionMathematical_Expression.register_function(ff);Mathematical_Expression.register_function(f);// 也可以直接使用它final double run = ff.run(1024);System.out.println(run);}
}

批量 序列化/注册 函数

在 1.3.4 版本中,您还可以直接在 Mathematical_Expression 中使用数据流的方式注册/序列化函数,这能够简化代码,下面是一个示例!

首先我们可以在这里将函数注册到库中!然后使用 Mathematical_Expression 来演示函数的序列化操作。

package utils;import core.Mathematical_Expression;
import core.calculation.function.Functions;
import core.calculation.function.ManyToOneNumberFunction;
import exceptional.WrongFormat;import java.io.FileOutputStream;
import java.io.IOException;@Functions({// 这里是需要被注册的两个函数 在这里标记一下 分别是 f 和 ff 以及 fff 几个函数"f(x) = x * x","ff(x) = f(x) + 1","fff(x) = x! + ff(x) + f(x)"
})
public class MAIN {public static void main(String[] args) throws IOException, WrongFormat {// 将函数注册一下Mathematical_Expression.register_function(MAIN.class);// 获取到 几个函数 的对象ManyToOneNumberFunction f = Mathematical_Expression.getFunction("f");ManyToOneNumberFunction ff = Mathematical_Expression.getFunction("ff");ManyToOneNumberFunction fff = Mathematical_Expression.getFunction("fff");// 直接将这几个函数输出到文件中try (final FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\zhao\\Desktop\\fsdownload\\f.ME")) {Mathematical_Expression.saveFunction(fileOutputStream, f, ff, fff);}}
}

接下来我们可以直接手动将文件读取到内存中并使用,在这里我们将演示 Mathematical_Expression 反序列化操作!

package utils;import core.Mathematical_Expression;
import core.calculation.function.ManyToOneNumberFunction;
import exceptional.WrongFormat;import java.io.FileInputStream;
import java.io.IOException;
import java.util.Map;public class MAIN {public static void main(String[] args) throws WrongFormat, IOException {// 将函数注册一下try (final FileInputStream fileInputStream = new FileInputStream("C:\\Users\\zhao\\Desktop\\fsdownload\\f.ME")) {// 直接在这里使用数据流来进行反序列化操作,这个数据流对应的文件包含的函数都会开始尝试注册final Map.Entry<Integer, Integer> integerIntegerEntry = Mathematical_Expression.register_function(fileInputStream);// 注册完毕之后在这里就可以查看到结果System.out.println("注册成功的数量:" + integerIntegerEntry.getKey());System.out.println("注册失败的数量:" + integerIntegerEntry.getValue());}// 然后我们就可以开始使用了 在这里的数据流中 包含的三个函数分别是 f ff ffffinal ManyToOneNumberFunction f = Mathematical_Expression.getFunction("f");final ManyToOneNumberFunction ff = Mathematical_Expression.getFunction("ff");final ManyToOneNumberFunction fff = Mathematical_Expression.getFunction("fff");System.out.println(f.run(10));System.out.println(ff.run(10));System.out.println(fff.run(10));}
}

下面是计算结果

[INFO][Calculation Management][24-03-22:01]] : A computing component is registered PrefixExpressionOperation
[INFO][Calculation Management][24-03-22:01]] : A computing component is registered BracketsCalculation2
[INFO][Calculation Management][24-03-22:01]] : A function is registered f
[INFO][Calculation Management][24-03-22:01]] : A function is registered ff
[INFO][Calculation Management][24-03-22:01]] : A function is registered fff
注册成功的数量:3
注册失败的数量:0
[INFO][Calculation Management][24-03-22:01]] : Get a function component from the manager. => f
[INFO][Calculation Management][24-03-22:01]] : Get a function component from the manager. => ff
[INFO][Calculation Management][24-03-22:01]] : Get a function component from the manager. => fff
[INFO][functionFormulaCalculation_temp][24-03-22:01]] : Use shared pool data. The identity of the data is: functionFormulaCalculation_temp(10.0*10.0)
100.0
[INFO][functionFormulaCalculation_temp][24-03-22:01]] : No Use shared pool: functionFormulaCalculation_temp(f(10.0) + 1)
[INFO][Calculation Management][24-03-22:01]] : Get a function component from the manager. => f
[INFO][functionFormulaCalculation_temp][24-03-22:01]] : Use shared pool data. The identity of the data is: functionFormulaCalculation_temp(10.0*10.0)
101.0
[INFO][functionFormulaCalculation_temp][24-03-22:01]] : No Use shared pool: functionFormulaCalculation_temp(10.0! + ff(10.0) + f(10.0))
[INFO][Calculation Management][24-03-22:01]] : Get a function component from the manager. => f
[INFO][functionFormulaCalculation_temp][24-03-22:01]] : Use shared pool data. The identity of the data is: functionFormulaCalculation_temp(10.0*10.0)
[INFO][Calculation Management][24-03-22:01]] : Get a function component from the manager. => ff
[INFO][functionFormulaCalculation_temp][24-03-22:01]] : Use shared pool data. The identity of the data is: functionFormulaCalculation_temp(f(10.0) + 1)
3629001.0

更多信息

  • Switch to English Document
  • mathematical-expression-py
  • mathematical-expression-JS
  • mathematical-expression-C++

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/789200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么蓝牙信道探测将引领高精度定位服务?

从蓝牙耳机到智能家居设备&#xff0c;蓝牙技术因其成熟的音频流和数据传输功能已成为我们生活中的一部分。一项新技术——蓝牙信道探测&#xff08;Bluetooth Channel Sounding&#xff09;正向高精度定位服务市场迈进。 本文信驰达&#xff08;RF-star&#xff09;将介绍蓝牙…

数码论坛系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)电子科技数码爱好者交流信息新闻畅聊讨论评价

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读300套最新项目持续更新中..... 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含ja…

使用TCP协议就一定零丢包了吗?

简述数据包发送流程 为了简化模型&#xff0c;我们把中间的服务器给省略掉&#xff0c;假设这是个端到端的通信。且为了保证消息的可靠性&#xff0c;它们之间用的是TCP协议进行通信。 为了发送数据包&#xff0c;两端首先会通过三次握手&#xff0c;建立TCP连接。 一个数据包&…

Unity | Shader基础知识(第十一集:什么是Normal Map法线贴图)

目录 前言 一、图片是否有法线贴图的视觉区别 二、有视觉区别的原因 三、法线贴图的作用 四、信息是如何存进去的 五、自己写一个Shader用到法线贴图 六、注意事项 七、作者的话 前言 本小节会给大家解释&#xff0c;什么是法线贴图&#xff1f;为什么法线贴图会产生深…

Spring源码分析(BeanFactory)

文章目录 Spring源码分析&#xff08;BeanFactory&#xff09;一、BeanFactory二、ApplicationContext 的父系1、HierarchicalBeanFactory2、ListableBeanFactory3、EnvironmentCapable4、ApplicationEventPublisher5、MessageSource6、ResourcePatternResolver 三、Applicatio…

了解这些技术:Flutter应用顺利登陆iOS平台的步骤与方法

引言 &#x1f680; Flutter作为一种跨平台的移动应用程序开发框架&#xff0c;为开发者提供了便利&#xff0c;使他们能够通过单一的代码库构建出高性能、高保真度的应用程序&#xff0c;同时支持Android和iOS两个平台。然而&#xff0c;完成Flutter应用程序的开发只是第一步…

【鹅厂摸鱼日记(一)】(工作篇)认识八大技术架构

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:重生之我在鹅厂摸鱼⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多知识   &#x1f51d;&#x1f51d; 认识八大架构 1. 前言2. 架构简介&…

【Spring】SpringBoot整合ShardingSphere并实现多线程分批插入10000条数据(进行分库分表操作)。

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 一、ShardingSphere简介 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈&#xff0c;它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar&#xff08;计划中&#xff09;这3款相互独立的产品组成…

【2024 信息素养大赛c++模拟题】算法创意实践挑战赛(基于 C++)

一、 比赛简介 国务院发布《国务院关于印发新一代人工智能发展规划的通 知》&#xff0c;明确实施全民智能教育项目。教育部印发《2019 年教育信息 化和网络安全工作要点》&#xff0c;推动在中小学阶段设置人工智能相关课 程&#xff0c;逐步推广编程教育。本赛项是在贯彻…

Linux学习笔记————C 语言版 LED 灯实验

这里写目录标题 一、实验程序编写二、 汇编部分实验程序编写三、C 语言部分实验程序编写四、编译下载验证 汇编 LED 灯实验中&#xff0c;我们讲解了如何使用汇编来编写 LED 灯驱动&#xff0c;实际工作中是很少用到汇编去写嵌入式驱动的&#xff0c;毕竟汇编太难&#xff0c;而…

用于HUD平视显示器的控制芯片:S2D13V40

一款利用汽车抬头显示技术用于HUD平视显示器的控制芯片:S2D13V40。HUD的全称是Head Up Display&#xff0c;即平视显示器&#xff0c;以前应用于军用飞机上&#xff0c;旨在降低飞行员需要低头查看仪表的频率。起初&#xff0c;HUD通过光学原理&#xff0c;将驾驶相关的信息投射…

1.Git是用来干嘛的

本文章学习于【GeekHour】一小时Git教程&#xff0c;来自bilibili Git就是一个文件管理系统&#xff0c;这样说吧&#xff0c;当多个人同时在操作一个文件的同时&#xff0c;很容易造成紊乱&#xff0c;git就是保证文件不紊乱产生的 包括集中式管理系统和分布式管理系统 听懂…

00 - Logic Circuit 简介 -- 与或非门

---- 整理自B站UP主 踌躇月光 的视频 1. Logic Circuit Logic Circuit 下载地址 界面如下&#xff0c;实际使用可下载体验 2. 与或非门

HTML常用的图片标签和超链接标签

目录 一.常用的图片标签和超链接标签&#xff1a; 1.超链接标签&#xff1a; 前言: 超链接的使用&#xff1a; target属性: 1)鼠标样式&#xff1a; 2)颜色及下划线: 总结: 2.图片标签&#xff1a; 前言: img的使用: 设置图片&#xff1a; 1.设置宽度和高度: 2.HTM…

排序算法-归并排序

Leetcode链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 归并&#xff1a;将原始数组划分为若干个子数组&#xff0c;然后将这些子数组分别排序&#xff0c;最后再将已排序的子数组合并成一个有序的数组。是一种分治思想 思路&#xff1a; 1.分 2.治 3.怎么治 …

力扣1047. 删除字符串中的所有相邻重复项

思路&#xff1a;消消乐的感觉&#xff0c;就先想到栈&#xff1b;用一个栈存放遍历过的元素&#xff0c;和遍历中的下一个元素相比&#xff0c;相同则出栈&#xff0c;不同则入栈&#xff0c;最终栈内剩余的就是不相同的元素。 class Solution {public String removeDuplicat…

C语言第三十九弹---预处理(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 预处理 1、预定义符号 2、#define定义常量 3、#define定义宏 4、带有副作用的宏参数 5、宏替换的规则 6、宏和函数的对比 总结 在C语言中&#xff0c;预处…

【C++】多态的原理

目录 一、虚函数表 1、虚函数表的定义 2、虚函数表特性 3、虚表的打印 二、多态的原理 三、多态的相关问题 1、指针偏移问题 2、输出的程序是什么&#xff1f; 3、输出的程序是什么&#xff1f; 【前言】 上一篇我们学习了多态的基础知识&#xff0c;这一篇我将带着大…

HarmonyOS 应用开发之通过数据管理服务实现数据共享静默访问

场景介绍 典型跨应用访问数据的用户场景下&#xff0c;数据提供方会存在多次被拉起的情况。 为了降低数据提供方拉起次数&#xff0c;提高访问速度&#xff0c;OpenHarmony提供了一种不拉起数据提供方直接访问数据库的方式&#xff0c;即静默数据访问。 静默数据访问通过数据…

Incus:新一代容器与虚拟机编排管理引擎

Incus是什么&#xff1f; Incus是一个用于编排管理应用型容器、系统型容器及虚拟机实例的管理工具。它是对 Canonical LXD 的继承与发展&#xff0c;引入了更多的存储驱动支持。 Incus项目的产品地址&#xff1a;Linux Containers - Incus - Introduction 在 LXC-Incus 项目…