转化字符串表达式为数学公式并算出结果
2009-10-16 21:55
369 查看
/*
* FormulaCalculator.java
*
* Created on 2007年9月18日, 上午11:40
* @title 转化字符串表达式为数学公式并算出结果
* @description 转化字符串表达式为数学公式并算出结果
* 注意:为了区分负号,这边使用#代替减号
* 使用方法:
* 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.java
*
* Created on 2007年9月18日, 上午11:40
* @title 转化字符串表达式为数学公式并算出结果
* @description 转化字符串表达式为数学公式并算出结果
* 注意:为了区分负号,这边使用#代替减号
* 使用方法:
* 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
- 取得一个字符串表达式的计算结果(实现方法一)