最新活动:电脑PC端+手机端+微网站+自适应网页多模板选择-建站388元起价!!!
当前位置:主页 > 网站建设 > 使用java处理字符串公式运算的方法建站知识

使用java处理字符串公式运算的方法建站知识

时间:2023-05-24 09:05:24 阅读: 文章分类: 网站建设 作者: 网站编辑员

导读:1建站知识在改进一个关于合同的项目时,有个需求,就是由于合同中非数据项的计算公式会根据年份而进行变更,而之前是将公式硬编码到系统中的,只要时间一变,系统就没法使用了,因此网站seo优化培训网站优化seo培训。

网站seo优化培训网站优化seo培训在改进一个关于合同的项目时,有个需求,就是由于合同中非数据项的计算公式会根据年份而进行变更,而之前是将公式硬编码到系统中的,只要时间一变,系统就没法使用了,因此要求合同中各个非基础数据的项都能自定义公式,根据设置的公式来自动生成报表和合同中的数据。     显然定义的公式都是以字符串来存储到数据库的,可是java中没有这种执行字符串公式的工具或者类,而且是公式可以嵌套一个中间公式。比如:基础数据dddd是56,而一个公式是依赖dddd的,eeee=dddd*20,而最终的公式可能是这样:eeee*-12+13-dddd+24。可知eeee是一个中间公式,所以一个公式的计算需要知道中间公式和基础数据。   这好像可以使用一个解释器模式来解决,但是我没有成功,因为括号的优先级是一个棘手的问题,后来又想到可以使用freemarker类似的模板引擎或者java6之后提供的ScriptEngine 脚本引擎,做了个实验,脚本引擎可以解决,但是这限制了必须使用java6及以上的版本。最终功夫不负有心人,终于找到了完美解决方案,即后缀表达式。我们平时写的公式称作中缀表达式,计算机处理起来比较困难,所以需要先将中缀表达式转换成计算机处理起来比较容易的后缀表达式。   将中缀表达式转换为后缀表达式具体算法规则:见后缀表达式     a.若为 '(',入栈;   b.若为 ')',则依次把栈中的的运算符加入后缀表达式中,直到出现'(',从栈中删除'(' ;   c.若为 除括号外的其他运算符 ,当其优先级高于栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止。   ·当扫描的中缀表达式结束时,栈中的的所有运算符出栈;    我们提出的要求设想是这样的:   复制代码 代码如下:     public class FormulaTest { @Test public void testFormula() { //基础数据 Map<String, BigDecimal> values = new HashMap<String, BigDecimal>(); values.put("dddd", B网seo优化趋势igDecimal.valueOf(56d));   //需要依赖的其他公式 Map<String, String> formulas = new HashMap<String, String>(); formulas.put("eeee", "#{dddd}*20"); 网站seo优化   //需要计算的公式 String expression = "#{eeee}*-12+13-#{dddd}+24";   BigDecimal result = FormulaParser.parse(expression, formulas, values); Assert.assertEquals(result, BigDecimal.valueOf(-13459.0)); } }     以下就是解决问题的步骤: 1、首先将所有中间变量都替换成基础数据   FormulaParser的finalExpression方法会将所有的中间变量都替换成基础数据,就是一个递归的做法   复制代码 代码如下:     public class FormulaParser { /** * 匹配变量占位符的正则表达式 */ private static Pattern pattern = Pattern.compile("\\#\\{(.+?)\\}");   /** * 解析公式,并执行公式计算 *  * @param formula * @param formulas * @param values * @return */ public static BigDecimal parse(String formula, Map<String, String> formulas, Map<String, BigDecimal> values) { if (formulas == n建设网站公司ull)formulas = Collections.emptyMap(); if (values == null)values = Collections.emptyMap(); String expression = finalExpression(formula, formulas, values); return new Calculator().eval(expression); }   /** * 解析公式,并执行公式计算 *  * @param formula * @param values * @return */ public static BigDecimal parse(String formula, Map<String, BigDecimal> values) { if (values == null)values = Collections.emptyMap(); return parse(formula, Collections.<String, String> emptyMap(), values); }   /** * 解析公式,并执行公式计算 *  * @param formula * @return */ public static BigDecimal parse(String formula) { return parse(formula, Collections.<String, String> emptyMap(), Collections.<String, BigDecimal> emptyMap()); }   /** * 将所有中间变量都替换成基础数据 *  * @param expression * @param formulas * @param values * @return */ private static String finalExpression(String expression, Map<String, String> formulas, Map<String, BigDecimal> values) { Matcher m = pattern.matcher(expression); if (!m.find())return expression;   m.reset();   StringBuffer buffer = new StringBuffer(); while (m.find()) { String group = m.group(1); if (formulas != null && formulas.containsKey(group)) { String formula = formulas.get(group); m.appendReplacement(buffer, '(' + formula + ')'); } else if (values != null && values.containsKey(group)) { BigDecimal value = values.get(group); m.appendReplacement(buffer,value.toPlainString()); }else{ throw new IllegalArgumentException("expression '"+expression+"' has a illegal variable:"+m.group()+",cause veriable '"+group+"' not being found in formulas or in values."); } } m.appendTail(buffer); return finalExpression(buffer.toString(), formulas, values); } }     2、将中缀表达式转换为后缀表达式   Calculator的infix2Suffix将中缀表达式转换成了后缀表达式   3、计算后缀表达式     Calculator的evalInfix计算后缀表达式   复制代码 代码如下:相关网站seo优化培训网站优化seo培训。

关键词标签: 字符串 公式

声明: 本文由我的SEOUC技术文章主页发布于:2023-05-24 ,文章使用java处理字符串公式运算的方法建站知识主要讲述字符串,公式,使用java处理字符串公式运算的方法网站建设源码以及服务器配置搭建相关技术文章。转载请保留链接: https://www.seouc.com/article/web_6522.html

我的IDC 网站建设技术SEOUC.COM
专注网站建设,SEO优化,小程序设计制作搭建开发定制网站等,数千家网站定制开发案例,网站推广技术服务。
  • 5000+合作客服
  • 8年从业经验
  • 150+覆盖行业
  • 最新热门源码技术文章