使用java處理字符串公式運算的方法建站知識
導(dǎo)讀:1建站知識在改進一個關(guān)于合同的項目時,有個需求,就是由于合同中非數(shù)據(jù)項的計算公式會根據(jù)年份而進行變更,而之前是將公式硬編碼到系統(tǒng)中的,只要時間一變,系統(tǒng)就沒法使用了,因此網(wǎng)站seo優(yōu)化培訓(xùn)網(wǎng)站優(yōu)化seo培訓(xùn)。
在改進一個關(guān)于合同的項目時,有個需求,就是由于合同中非數(shù)據(jù)項的計算公式會根據(jù)年份而進行變更,而之前是將公式硬編碼到系統(tǒng)中的,只要時間一變,系統(tǒng)就沒法使用了,因此要求合同中各個非基礎(chǔ)數(shù)據(jù)的項都能自定義公式,根據(jù)設(shè)置的公式來自動生成報表和合同中的數(shù)據(jù)。
顯然定義的公式都是以字符串來存儲到數(shù)據(jù)庫的,可是java中沒有這種執(zhí)行字符串公式的工具或者類,而且是公式可以嵌套一個中間公式。比如:基礎(chǔ)數(shù)據(jù)dddd是56,而一個公式是依賴dddd的,eeee=dddd*20,而最終的公式可能是這樣:eeee*-12+13-dddd+24。可知eeee是一個中間公式,所以一個公式的計算需要知道中間公式和基礎(chǔ)數(shù)據(jù)。
這好像可以使用一個解釋器模式來解決,但是我沒有成功,因為括號的優(yōu)先級是一個棘手的問題,后來又想到可以使用freemarker類似的模板引擎或者java6之后提供的ScriptEngine 腳本引擎,做了個實驗,腳本引擎可以解決,但是這限制了必須使用java6及以上的版本。最終功夫不負有心人,終于找到了完美解決方案,即后綴表達式。我們平時寫的公式稱作中綴表達式,計算機處理起來比較困難,所以需要先將中綴表達式轉(zhuǎn)換成計算機處理起來比較容易的后綴表達式。
將中綴表達式轉(zhuǎn)換為后綴表達式具體算法規(guī)則:見后綴表達式
a.若為 '(',入棧;
b.若為 ')',則依次把棧中的的運算符加入后綴表達式中,直到出現(xiàn)'(',從棧中刪除'(' ;
c.若為 除括號外的其他運算符 ,當(dāng)其優(yōu)先級高于棧頂運算符時,直接入棧。否則從棧頂開始,依次彈出比當(dāng)前處理的運算符優(yōu)先級高和優(yōu)先級相等的運算符,直到一個比它優(yōu)先級低的或者遇到了一個左括號為止。
·當(dāng)掃描的中綴表達式結(jié)束時,棧中的的所有運算符出棧;
我們提出的要求設(shè)想是這樣的:
復(fù)制代碼 代碼如下:
public class FormulaTest {
@Test
public void testFormula() {
//基礎(chǔ)數(shù)據(jù)
Map<String, BigDecimal> values = new HashMap<String, BigDecimal>();
values.put("dddd", B網(wǎng)seo優(yōu)化趨勢igDecimal.valueOf(56d));
//需要依賴的其他公式
Map<String, String> formulas = new HashMap<String, String>();
formulas.put("eeee", "#{dddd}*20");
網(wǎng)站seo優(yōu)化
//需要計算的公式
String expression = "#{eeee}*-12+13-#{dddd}+24";
BigDecimal result = FormulaParser.parse(expression, formulas, values);
Assert.assertEquals(result, BigDecimal.valueOf(-13459.0));
}
}
以下就是解決問題的步驟:
1、首先將所有中間變量都替換成基礎(chǔ)數(shù)據(jù)
FormulaParser的finalExpression方法會將所有的中間變量都替換成基礎(chǔ)數(shù)據(jù),就是一個遞歸的做法
復(fù)制代碼 代碼如下:
public class FormulaParser {
/**
* 匹配變量占位符的正則表達式
*/
private static Pattern pattern = Pattern.compile("\\#\\{(.+?)\\}");
/**
* 解析公式,并執(zhí)行公式計算
*
* @param formula
* @param formulas
* @param values
* @return
*/
public static BigDecimal parse(String formula, Map<String, String> formulas, Map<String, BigDecimal> values) {
if (formulas == n建設(shè)網(wǎng)站公司ull)formulas = Collections.emptyMap();
if (values == null)values = Collections.emptyMap();
String expression = finalExpression(formula, formulas, values);
return new Calculator().eval(expression);
}
/**
* 解析公式,并執(zhí)行公式計算
*
* @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);
}
/**
* 解析公式,并執(zhí)行公式計算
*
* @param formula
* @return
*/
public static BigDecimal parse(String formula) {
return parse(formula, Collections.<String, String> emptyMap(), Collections.<String, BigDecimal> emptyMap());
}
/**
* 將所有中間變量都替換成基礎(chǔ)數(shù)據(jù)
*
* @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、將中綴表達式轉(zhuǎn)換為后綴表達式
Calculator的infix2Suffix將中綴表達式轉(zhuǎn)換成了后綴表達式
3、計算后綴表達式
Calculator的evalInfix計算后綴表達式
復(fù)制代碼 代碼如下:相關(guān)網(wǎng)站seo優(yōu)化培訓(xùn)網(wǎng)站優(yōu)化seo培訓(xùn)。
聲明: 本文由我的SEOUC技術(shù)文章主頁發(fā)布于:2023-05-24 ,文章使用java處理字符串公式運算的方法建站知識主要講述字符串,公式,使用java處理字符串公式運算的方法網(wǎng)站建設(shè)源碼以及服務(wù)器配置搭建相關(guān)技術(shù)文章。轉(zhuǎn)載請保留鏈接: http://www.bifwcx.com/article/web_6522.html
為你推薦與使用java處理字符串公式運算的方法建站知識相關(guān)的文章
-
通王TWCMS 2.0.3網(wǎng)站模板程序下載
(126)人喜歡 2024-01-15 -
Windows官方原版在哪里下載
(175)人喜歡 2024-01-15 -
WordPress網(wǎng)站模板發(fā)帖標(biāo)題顏色設(shè)置
(131)人喜歡 2024-01-07 -
修改discuz論壇帖子標(biāo)題80字符的長度限制
(249)人喜歡 2024-01-07 -
wordpress程序調(diào)用不帶超鏈接的Tag標(biāo)簽
(234)人喜歡 2024-01-05 -
網(wǎng)站在不同時期需調(diào)整內(nèi)容更新的方向
(112)人喜歡 2023-08-12