文档章节

Java处理数学公式得出结果

杨润康Bla
 杨润康Bla
发布于 2016/05/18 18:04
字数 1029
阅读 30
收藏 1
点赞 2
评论 0

支持含有字母的复杂表达式、不含字母的纯数学表达式

先上测试程序,后面有源码:
1.纯数字的算式测试

    public static void main(String[] args) throws Exception {
        String express = "(100-5+45)*88.8/(5/94+584)";
        Double result = MathFormulaUtil.getNumberResult(express);
        System.out.println(result); //结果:21.28573250031876
    }

2.带有字母的公式测试

public static void main(String[] args) throws Exception {
        String express = "(((x+y)/(z+x)*q)+100-99)*565";
        //输入参数
        double[] param = new double[]{45,89,200,45,66};
        Double result =MathFormulaUtil.getExpressionResult(express, param);
        System.out.println(result); //结果:20960.346938775518
    }

下面是程序源码:

/* 说明: 首先需要导入2个jar包: expression4jCFG.jar expression4j.jar 上面2个jar包依赖于日志记录,所以还需要导入下面几个日志包. slf4j-api-1.5.11.jar log4j-1.2.17.jar slf4j-log4j12-1.5.11.jar 上面的jar包在文章的末尾有下载 */
package com.usi.jrwl.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import fr.expression4j.basic.MathematicalElement;
import fr.expression4j.core.Expression;
import fr.expression4j.core.Parameters;
import fr.expression4j.factory.ExpressionFactory;
import fr.expression4j.factory.NumberFactory;
/** * 输入数学公式即可计算结果 * @author 杨润康 */
public class MathFormulaUtil {

    /** * 根据用户输入的数学算式返回表达式对象 * @param expressionString 用户输入 数学算式 * @param params 按照变量的位置为变量输入[对应]的值 * @return 计算结果 * @throws Exception * * note:在英文输入法的状态下输入 */
    public static Double getExpressionResult(String expressionString,double...params) throws Exception{
        // ( ) + - * / 0-9是数学中的表达式 其余的部分是变量 x y z 等等
        //注意消除空格
        //第一步 去除空格
        expressionString.trim().replace(" ","");
        //第二步 获取每个字符串的每个字符 后面主要做过滤
        String[] expressArgs = expressionString.split("");
        //创建过滤器 过滤出来除 ( ) + - * / 数字 0-9 之外的其余字符
        List<String> filters = Arrays.asList("(",")","+","-","*","/","0","1","2","3","4","5","6","7","8","9");
        //过滤出结果 即过滤出用户输入的变量
        List<String> vars = new ArrayList<String>();//存放过滤结果 
        int count = -1;
        for(String arg : expressArgs){
            count++; //计数 从0
            if(!filters.contains(arg)){ //字符不在工具类中
                if(!arg.equals("")){  //空格不能加入其中 
                    //处理重复变量的问题
                    if(vars.contains(arg)){ //如果已经过滤的结果中包含了当前循环的编号 追加随机数 避免让key值不一样,这样不会发生替换
                        String argRandom = arg+getRandom(); // f(x,x12) 中变了,还得让 = (x+x2)中对应的变量也变 处理方法 count
                        //替换原表达式,即等号后面的部分
                        String oldChar = expressionString.substring(count-1); //等号 替换循环位置后面的部分 后面原字符
                        //不能直接替换 这样会都替换掉 我只是替换循环位置后面的部分
                        String repStrLater = oldChar.replace(oldChar, argRandom);
                        //更新等号后面的表达式 截掉旧的替换新的
                        expressionString = expressionString.substring(0,count-1)+repStrLater+expressionString.substring(count);
                        vars.add(argRandom);
                        count = count +32; //补充随机字符串的剩余长度,,以保证坐标准确
                    }else{ //不包含 正常添加
                        vars.add(arg);
                    }
                }
            }
        }
        //构建表达式 "f(x,y,z,..)="
        StringBuilder expressionHead = new StringBuilder("f(");
        for(String v : vars){
            expressionHead.append(v+",");
        }
        //将最后一个 , 去掉
        expressionHead.setLength(expressionHead.length()-1);
        expressionHead.append(")=");
        //完整的表达式
        String expressionAll = expressionHead + expressionString;
        //创建表达式对象
        Expression expression = ExpressionFactory.createExpression(expressionAll);

        //为参数赋值放入List中 顺序不能乱
        List<MathematicalElement> mes = new ArrayList<MathematicalElement>();

        //输入的参数 params
        //构建数学元素
        for (int i = 0; i < params.length; i++) {
            mes.add(NumberFactory.createReal(params[i]));
        }

        //从表达式工厂创建一个空的参数
        Parameters parameters = ExpressionFactory.createParameters();
        //对应参数赋值
        for(int i=0;i<vars.size();i++){
            //这边是键值的形式存储的,所以第二个,传过来的第二个x的值,或由于键是一样的,而替换掉第一次键对应的值,及2--->4,键还是那个键 x
            //解决方法 键的区分 : 过滤用户表达式中的变量时加一个方法 即 与已经过滤出来结果再此比较,如果在出现一样的键,重新命名采用追加随机数的方式 
            parameters.addParameter(vars.get(i),mes.get(i));//vars 变量 mes 变量对应的值 
        }
        //返回结果
        return expression.evaluate(parameters).getRealValue();
    }

    /** * 支持纯数字计算 * @param expressionString 用户输入 数学算式 * @return 计算结果 * @throws Exception 异常 */
    public static Double getNumberResult(String expressionString) throws Exception{
        Expression expression = ExpressionFactory.createExpression("f()="+expressionString);
        return expression.evaluate(null).getRealValue();
    }

    /** * 生成随机数 */
    public  static String getRandom(){
        String s = UUID.randomUUID().toString();
        return s.substring(0, 8) + s.substring(9, 13) + s.substring(14, 18) + s.substring(19, 23) + s.substring(24);
    }
}

jar包下载地址:http://sourceforge.net/projects/expression4j/

本文转载自:http://blog.csdn.net/yangrunkangbla/article/details/50222063

共有 人打赏支持
杨润康Bla
粉丝 14
博文 76
码字总数 0
作品 0
合肥
后端工程师
Scala和Java在多核处理性能的一次对比和思考

今天在网络上看到了一篇关于Scala和java多线程对比的文章《Simple Scala actor Vs java Thread Vs Kilim Test,原文链接:http://www.blogjava.net/BlueDavy/archive/2009/11/25/303662.html......

qinhui99
2012/05/13
0
3
Scala学习笔记(2)-基础语法

秉着简洁而不失完整的的原则,这章只把Scala主要语法和与Java不同的内容列出来,以后章节也如此,内容以简洁为主,太长了自己都被吓着了,也没耐心看下去。 1.Scala解释器使用,这里不做介绍...

山海经
2013/08/25
0
0
【转】JDK,JRE,JVM三者之间的关系

如果安装了JDK,会发同你的电脑有两套JRE,一套位于 jre 另外一套位于 C:Program FilesJavaj2re1.4.1_01 目录下,后面这套比前面那套少了Server端的Java虚拟机,不过直接将前面那套的Server端...

mj4738
2012/01/15
0
0
一个java初学者的心得体验!

学习了一学期的Java课程,觉得是该总结自己的心得体会了。开始学习任何一门课(包括java),兴趣最重要。 还记得我编写的第一个经典程序“Hello Word”。从那时起我已开始走进Java的世界。 当时...

嘿你好夏天
01/12
0
0
深入Java核心:JVM中的栈和局部变量

Java开发中,每当我们在程序中使用new生成一个对象,对象的引用存放在栈里,而对象是存放在堆里的。可以看出栈在Java核心的重要位置。今天我们就继续深入Java核心这个系列,为您介绍Java中的...

郭二翔
2011/12/19
0
0
JVM内存最大能调多大分析【经典】

上次用weblogic 把 -XmxXXXX 设成2G,就启动不起来,设小点就起来了,当时很气,怎么2G都起不了,今天在看到了一篇解释,转过来了 这 次一位老友提出了这个问题,记得当年一个java高手在blo...

月下狼
2015/01/24
0
0
通过Java字节码发现有趣的内幕之String篇(一)

很多时候我们在编写Java代码时,判断和猜测代码问题时主要是通过运行结果来得到答案,本博文主要是想通过Java字节码的方式来进一步求证我们已知的东西。这里没有对Java字节码知识进行介绍,如...

jaffa
2015/08/28
0
7
Linux 命令个人收集(慢慢更新)

-进程相关 查看详细系统进程信息 ps -aux 查看端口被哪个进程占用 lsof -i:2181结果:COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEjava 778 ubuntu 100u IPv4 6162328 0t0 TCP localh......

iJarobot
2014/02/25
0
0
java.lang.OutOfMemoryError: Java heap space

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 今天我想说说这个有趣的问题,这的确是个让人费解的是error 问题来源: 这个问题一般会出在myecplise 和ecplise ,...

soul_mate
2014/05/03
0
0
Java 基础:hashCode方法

Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 一、前言 泥瓦匠最近被项目搞的天昏地暗。发现有些要给自己一些目标,关于技术的目标: 专注很重要。专注Java 基础 + H5...

泥沙砖瓦浆木匠
2015/04/27
0
4

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Win10专业版安装GIT后使用Git Bash闪退解决办法

百度后把过程和最终解决办法记录下来: 百度首先出来的解决办法如下: 来自:https://segmentfault.com/q/1010000012722511?sort=created 重启电脑 重新安装 安装到C盘 尝试网上的教程 \Git...

特拉仔
14分钟前
0
0
设计模式

1.装饰器模式 概念 允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰者可以在所委托被装饰者的行为之前或之后加上自己的行为,以达到特定的目的。 实现 增加一个修饰类包裹原来的...

EasyProgramming
28分钟前
1
0
用python2和opencv进行人脸识别

一、安装cv2 sudo apt-get install python-opencv opencv-data 二、 Haar特征分类器 Haar特征分类器就是一个XML文件,该文件中会描述人体各个部位的Haar特征值。包括人脸、眼睛、嘴唇等等。 ...

wangxuwei
28分钟前
0
0
python模板中循环字典

{% for k,v in user.items %} {{ k}} {{ v}} {% endfor %}

南桥北木
57分钟前
0
0
Java8系列之重新认识HashMap

简介 Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap、Hashtable、LinkedHashMap和TreeMap,类继承关系如下图所示: 下面针对各个实现类...

HOT_POT
今天
0
0
获取调用方的className

/** * 获取调用方的class * @return */private static String getInvoke() { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); S......

iborder
今天
0
0
深入了解一下Redis的内存模型!

一前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分。 我们使用Redis时,会接触Redis的5种对象类型(字符...

Java填坑之路
今天
1
0
从实践出发:微服务布道师告诉你Spring Cloud与Spring Boot他如何选择

背景 随着公司业务量的飞速发展,平台面临的挑战已经远远大于业务,需求量不断增加,技术人员数量增加,面临的复杂度也大大增加。在这个背景下,平台的技术架构也完成了从传统的单体应用到微...

老道士
今天
1
0
大数据学习的各个阶段

第一阶段:Linux课程讲解Linux基础操作,讲的是在命令行下进行文件系统的操作,这是Hadoop学习的基础,后面的所有视频都是基于linux操作的。鉴于很多学员没有linux基础,特增加该内容,保证零linux...

董黎明
今天
0
0
CVE-2013-0077 堆溢出分析

找了很久才发现这个环境比较容易搭建分析... 环境: 系统---Win XP SP3 漏洞程序:QQPlayer 3.7.892.400 出错DLL:quartz.dll 6.5.2600.5512 调试工具:x32db+gflag.exe 过程: 首先gflag设置...

Explorer0
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部