转化字符串表达式为数学公式并算出结果
2010-04-01 17:04
525 查看
/*
* FormulaCalculator calculator=new FormulaCalculator();
* calculator.getResult("10.23#20.67*(5.12+7.82)/2",2);
* v1.0.0 created by chenfc
*
*/
package org.jceun;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FormulaCalculator ... {
private boolean isRightFormat = true ;
public String DIVISOR_EQUALS_ZERO = " 0.0 " ; // 除数为零时的返回值
/** */ /**
* 为了区分负号,这边使用#代替减号
* @param formula 字符串表达式
* @return 返回公式计算结果
*/
public double getResult(String formula) ... {
double returnValue = 0 ;
try ... {
returnValue = doAnalysis(formula);
} catch (NumberFormatException nfe) ... {
System.out.println( " 公式格式有误,请检查: " + formula);
} catch (Exception e) ... {
e.printStackTrace();
}
if ( ! isRightFormat) ... {
System.out.println( " 公式格式有误,请检查: " + formula);
}
return returnValue;
}
/** */ /**
* 采用BigDecimal.ROUND_HALF_UP方式返回指定精度的运算结果
* @param formula 公式
* @param decimalPlace 要保留的小数位数
* @return 返回公式计算结果
*/
public String getResult(String formula, int decimalPlace) ... {
return getResult(formula,decimalPlace,BigDecimal.ROUND_HALF_UP);
}
/** */ /**
* 返回指定精度及舍去尾数的策略的运算结果
* @param formula 公式
* @param decimalPlace 要保留的小数位数
* @param roundMethod 舍去尾数的策略
* 可取值有BigDecimal.ROUND_HALF_UP BigDecimal.ROUND_HALF_DOWN祥见BigDecimal
* @return 返回公式计算结果
*/
public String getResult(String formula, int decimalPlace, int roundMethod) ... {
double result = getResult(formula);
if (result == Double.MAX_VALUE)
return DIVISOR_EQUALS_ZERO;
else
return numberAround(result,decimalPlace,roundMethod);
}
private double doAnalysis(String formula) ... {
double returnValue = 0 ;
LinkedList < Integer > stack = new LinkedList < Integer > ();
int curPos = 0 ;
String beforePart = "" ;
String afterPart = "" ;
String calculator = "" ;
isRightFormat = true ;
while (isRightFormat && (formula.indexOf( ' ( ' ) >= 0 || formula.indexOf( ' ) ' ) >= 0 )) ... {
curPos = 0 ;
for ( char s : formula.toCharArray()) ... {
if (s == ' ( ' ) ... {
stack.add(curPos);
} else if (s == ' ) ' ) ... {
if (stack.size() > 0 ) ... {
beforePart = formula.substring( 0 , stack.getLast());
afterPart = formula.substring(curPos + 1 );
calculator = formula.substring(stack.getLast() + 1 , curPos);
formula = beforePart + doCalculation(calculator) + afterPart;
stack.clear();
break ;
} else ... {
System.out.println( " 有未关闭的右括号! " );
isRightFormat = false ;
}
}
curPos ++ ;
}
if (stack.size() > 0 ) ... {
System.out.println( " 有未关闭的左括号! " );
break ;
}
}
if (isRightFormat) ... {
returnValue = doCalculation(formula);
}
return returnValue;
}
/** */ /**
* 为了区分负号,这边使用#代替减号
*/
private double doCalculation(String formula) ... {
ArrayList < Double > values = new ArrayList < Double > ();
ArrayList < String > operators = new ArrayList < String > ();
int curPos = 0 ;
int prePos = 0 ;
for ( char s : formula.toCharArray()) ... {
if (s == ' + ' || s == ' # ' || s == ' * ' || s == ' / ' ) ... {
values.add(Double.parseDouble(formula.substring(prePos, curPos)
.trim()));
operators.add( "" + s);
prePos = curPos + 1 ;
}
curPos ++ ;
}
values.add(Double.parseDouble(formula.substring(prePos).trim()));
char op;
for (curPos = operators.size() - 1 ; curPos >= 0 ; curPos -- ) ... {
op = operators.get(curPos).charAt( 0 );
switch (op) ... {
case ' * ' :
values.add(curPos, values.get(curPos) * values.get(curPos + 1 ));
values.remove(curPos + 1 );
values.remove(curPos + 1 );
operators.remove(curPos);
break ;
case ' / ' :
if (values.get(curPos + 1 ).doubleValue() == 0.0 ) // 除数为零时
values.add(curPos, new Double(getDefaultValue()));
else
values.add(curPos, values.get(curPos) / values.get(curPos + 1 ));
values.remove(curPos + 1 );
values.remove(curPos + 1 );
operators.remove(curPos);
break ;
}
}
for (curPos = operators.size() - 1 ; curPos >= 0 ; curPos -- ) ... {
op = operators.get(curPos).charAt( 0 );
switch (op) ... {
case ' + ' :
values.add(curPos, values.get(curPos) + values.get(curPos + 1 ));
values.remove(curPos + 1 );
values.remove(curPos + 1 );
operators.remove(curPos);
break ;
case ' # ' :
values.add(curPos, values.get(curPos) - values.get(curPos + 1 ));
values.remove(curPos + 1 );
values.remove(curPos + 1 );
operators.remove(curPos);
break ;
}
}
return values.get( 0 ).doubleValue();
}
/** */ /**
* 对数字进行四舍五入
* @param dN 要四舍五入的数
* @param decimalPlace 精度
* @param roundMethod 舍去尾数的策略
* 可取值有BigDecimal.ROUND_HALF_UP BigDecimal.ROUND_HALF_DOWN祥见BigDecimal
*/
public String numberAround( double dN, int decimalPlace, int roundMethod) ... {
BigDecimal bd = new BigDecimal(String.valueOf(dN));
bd = bd.setScale(decimalPlace, roundMethod);
return String.valueOf(bd);
}
/** */ /**
* 对给定的字符串进行模式匹配
* @param str 要匹配的字符串
* @param regix 模式
* @return 返回匹配结果,成功为true,否则为false
* */
public boolean check(String str,String regix) ... {
boolean result = false ;
Pattern p = Pattern.compile(regix);
Matcher m = p.matcher(str);
result = m.matches();
return result;
}
}
* FormulaCalculator calculator=new FormulaCalculator();
* calculator.getResult("10.23#20.67*(5.12+7.82)/2",2);
* v1.0.0 created by chenfc
*
*/
package org.jceun;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FormulaCalculator ... {
private boolean isRightFormat = true ;
public String DIVISOR_EQUALS_ZERO = " 0.0 " ; // 除数为零时的返回值
/** */ /**
* 为了区分负号,这边使用#代替减号
* @param formula 字符串表达式
* @return 返回公式计算结果
*/
public double getResult(String formula) ... {
double returnValue = 0 ;
try ... {
returnValue = doAnalysis(formula);
} catch (NumberFormatException nfe) ... {
System.out.println( " 公式格式有误,请检查: " + formula);
} catch (Exception e) ... {
e.printStackTrace();
}
if ( ! isRightFormat) ... {
System.out.println( " 公式格式有误,请检查: " + formula);
}
return returnValue;
}
/** */ /**
* 采用BigDecimal.ROUND_HALF_UP方式返回指定精度的运算结果
* @param formula 公式
* @param decimalPlace 要保留的小数位数
* @return 返回公式计算结果
*/
public String getResult(String formula, int decimalPlace) ... {
return getResult(formula,decimalPlace,BigDecimal.ROUND_HALF_UP);
}
/** */ /**
* 返回指定精度及舍去尾数的策略的运算结果
* @param formula 公式
* @param decimalPlace 要保留的小数位数
* @param roundMethod 舍去尾数的策略
* 可取值有BigDecimal.ROUND_HALF_UP BigDecimal.ROUND_HALF_DOWN祥见BigDecimal
* @return 返回公式计算结果
*/
public String getResult(String formula, int decimalPlace, int roundMethod) ... {
double result = getResult(formula);
if (result == Double.MAX_VALUE)
return DIVISOR_EQUALS_ZERO;
else
return numberAround(result,decimalPlace,roundMethod);
}
private double doAnalysis(String formula) ... {
double returnValue = 0 ;
LinkedList < Integer > stack = new LinkedList < Integer > ();
int curPos = 0 ;
String beforePart = "" ;
String afterPart = "" ;
String calculator = "" ;
isRightFormat = true ;
while (isRightFormat && (formula.indexOf( ' ( ' ) >= 0 || formula.indexOf( ' ) ' ) >= 0 )) ... {
curPos = 0 ;
for ( char s : formula.toCharArray()) ... {
if (s == ' ( ' ) ... {
stack.add(curPos);
} else if (s == ' ) ' ) ... {
if (stack.size() > 0 ) ... {
beforePart = formula.substring( 0 , stack.getLast());
afterPart = formula.substring(curPos + 1 );
calculator = formula.substring(stack.getLast() + 1 , curPos);
formula = beforePart + doCalculation(calculator) + afterPart;
stack.clear();
break ;
} else ... {
System.out.println( " 有未关闭的右括号! " );
isRightFormat = false ;
}
}
curPos ++ ;
}
if (stack.size() > 0 ) ... {
System.out.println( " 有未关闭的左括号! " );
break ;
}
}
if (isRightFormat) ... {
returnValue = doCalculation(formula);
}
return returnValue;
}
/** */ /**
* 为了区分负号,这边使用#代替减号
*/
private double doCalculation(String formula) ... {
ArrayList < Double > values = new ArrayList < Double > ();
ArrayList < String > operators = new ArrayList < String > ();
int curPos = 0 ;
int prePos = 0 ;
for ( char s : formula.toCharArray()) ... {
if (s == ' + ' || s == ' # ' || s == ' * ' || s == ' / ' ) ... {
values.add(Double.parseDouble(formula.substring(prePos, curPos)
.trim()));
operators.add( "" + s);
prePos = curPos + 1 ;
}
curPos ++ ;
}
values.add(Double.parseDouble(formula.substring(prePos).trim()));
char op;
for (curPos = operators.size() - 1 ; curPos >= 0 ; curPos -- ) ... {
op = operators.get(curPos).charAt( 0 );
switch (op) ... {
case ' * ' :
values.add(curPos, values.get(curPos) * values.get(curPos + 1 ));
values.remove(curPos + 1 );
values.remove(curPos + 1 );
operators.remove(curPos);
break ;
case ' / ' :
if (values.get(curPos + 1 ).doubleValue() == 0.0 ) // 除数为零时
values.add(curPos, new Double(getDefaultValue()));
else
values.add(curPos, values.get(curPos) / values.get(curPos + 1 ));
values.remove(curPos + 1 );
values.remove(curPos + 1 );
operators.remove(curPos);
break ;
}
}
for (curPos = operators.size() - 1 ; curPos >= 0 ; curPos -- ) ... {
op = operators.get(curPos).charAt( 0 );
switch (op) ... {
case ' + ' :
values.add(curPos, values.get(curPos) + values.get(curPos + 1 ));
values.remove(curPos + 1 );
values.remove(curPos + 1 );
operators.remove(curPos);
break ;
case ' # ' :
values.add(curPos, values.get(curPos) - values.get(curPos + 1 ));
values.remove(curPos + 1 );
values.remove(curPos + 1 );
operators.remove(curPos);
break ;
}
}
return values.get( 0 ).doubleValue();
}
/** */ /**
* 对数字进行四舍五入
* @param dN 要四舍五入的数
* @param decimalPlace 精度
* @param roundMethod 舍去尾数的策略
* 可取值有BigDecimal.ROUND_HALF_UP BigDecimal.ROUND_HALF_DOWN祥见BigDecimal
*/
public String numberAround( double dN, int decimalPlace, int roundMethod) ... {
BigDecimal bd = new BigDecimal(String.valueOf(dN));
bd = bd.setScale(decimalPlace, roundMethod);
return String.valueOf(bd);
}
/** */ /**
* 对给定的字符串进行模式匹配
* @param str 要匹配的字符串
* @param regix 模式
* @return 返回匹配结果,成功为true,否则为false
* */
public boolean check(String str,String regix) ... {
boolean result = false ;
Pattern p = Pattern.compile(regix);
Matcher m = p.matcher(str);
result = m.matches();
return result;
}
}
相关文章推荐
- 转化字符串表达式为数学公式并算出结果
- 转化字符串表达式为数学公式并算出结果
- 转化字符串表达式为数学公式并算出结果
- 转化字符串表达式为数学公式并算出结果—实用类
- 转化字符串表达式为数学公式并算出结果
- 字符串转化为数学表达式并求值(后缀表达式)
- delphi中用算术表达式算出数学结果的方法。
- 计算字符串数学公式的结果
- asp.net字符串的数学表达式计算结果
- asp.net字符串的数学表达式计算结果
- python3如何将input输入的字符串转化为表达式并计算出结果
- 关于数学字符串公式的计算
- lua 字符串数学表达式运算
- 将字符串数字转化为数字相加再返回结果
- 如何在C#中运行数学表达式字符串
- 第一百零八节,JavaScript,内置对象,Global对象字符串编码解码,Math对象数学公式
- 通过给出的求值运算公式字符串得到其结果值
- 计算字符串中的简单数学公式
- 把字符串当公式计算,并得到他的结果如字符串为200*100
- 取得一个字符串表达式的计算结果(实现方法一)