?? expressionanalyze.java
字號(hào):
//ExpressionsAnalyze.java - 計(jì)算公式分析
/*
關(guān)于與用法的例子如下:
String expression = "num1 * num2 -num3/num1";
try{
ExpressionAnalyze analyze = new ExpressionAnalyze(expression,12,10,6);
catch(Exception e){
System.out.println(e.toString());
}
double temp = analyze.getResult();
System.out.println(temp);
需要注意的問題:
1. 一定要用try----catch語句;
2. 目前構(gòu)造函數(shù)可以有四種情況:
a. 只有一個(gè)參數(shù),用于接收公式,如 ExpressionAnalyze("abs(36-56)+90");
b. 兩個(gè)參數(shù),第一個(gè)用于接收公式,第二個(gè)用于接收傳值參數(shù)的值,
如 ExpressionAnalyze("cos(num)+45",926);
c. 三個(gè)參數(shù),第一個(gè)用于接收公式,另外兩個(gè)用于接收傳值參數(shù)的值,
如ExpressionAnalyze("cos(num)+flag",26,36);
d. 四個(gè)參數(shù),第一個(gè)用于接收公式,另外三個(gè)用于接收傳值參數(shù)的值,
如ExpressionAnalyze("cos(num)+num1*num2",6,10,32);
3. 所有的輸入值和返回值均用double類型以提高精度;
4. 公式中可以包含空格,ExpressionAnalyze 中包含有處理空格的 method 清除其中的空格;
5. 目前支持的運(yùn)算符包括 + - * / ( ) %(求余數(shù)) abs(求絕對(duì)值)
acos(反余弦) asin(反正弦) atan(反正切) cbrt(開立方)
ceil(求比被操作數(shù)大的最小整數(shù)) cos(余弦) cosh(雙曲余弦函數(shù))
exp(求ex ) floor(求比操作數(shù)小的最大整數(shù)) expm1(返回ex -1)
log(求以e為底的對(duì)數(shù)) log10(求以10為底的對(duì)數(shù)) log1p(返回1和被操作數(shù)和的自然對(duì)數(shù))
rint(返回和被操作數(shù)最接近的整數(shù)的double形式) round(四舍五入,返回long)
signum(正負(fù)號(hào)函數(shù)) sin(正弦函數(shù)) sinh(雙曲正弦) sqrt(開平方)
tan(正切) tanh(雙曲正切) toDegrees(將弧度轉(zhuǎn)化為角度)
toRadians(將角度轉(zhuǎn)化為弧度)共 31 種,并且括號(hào)可以嵌套使用。
各種運(yùn)算符的意義:
6. 負(fù)號(hào)"-"也可以正常使用,不過在使用中被操作數(shù)要加括號(hào),如 (-5);
但是公式開頭的符號(hào)可以不帶括號(hào),如 expression = "-cos(PI)+E";
7. 目前支持的常量包括:
a. 自然對(duì)數(shù)的底 "e",所用的符號(hào)為 "E"
b. 圓周率 "∏" ,所用的符號(hào)為 "PI"用法如 expression = "5 + cos (PI)";
8. 公式中也支持科學(xué)技術(shù)法,如 12.3e6 或者 12.3E6
*/
package ddpie.expressionanalyze;
public class ExpressionAnalyze {
//接受一個(gè)表達(dá)式參數(shù)的構(gòu)造函數(shù)
public ExpressionAnalyze(String expr) throws Exception{
this.expr = expr;
numOfParameter = 0;
try{
clearBlank();
seekOutElem();
compute();
}
catch (Exception e){
throw new Exception(e.toString());
}
}
//接受一個(gè)表達(dá)式參數(shù)、一個(gè)傳值參數(shù)的構(gòu)造函數(shù)
public ExpressionAnalyze(String expr,double value1) throws Exception{
this.expr = expr;
numOfParameter = 1;
this.value1 = value1;
try{
clearBlank();
seekOutElem();
compute();
}
catch (Exception e){
throw new Exception(e.toString());
}
}
//接受一個(gè)表達(dá)式參數(shù)、兩個(gè)傳值參數(shù)的構(gòu)造函數(shù)
public ExpressionAnalyze(String expr,double value1,double value2)
throws Exception
{
this.expr = expr;
numOfParameter = 2;
this.value1 = value1;
this.value2 = value2;
try{
clearBlank();
seekOutElem();
compute();
}
catch (Exception e){
throw new Exception(e.toString());
}
}
//接受一個(gè)表達(dá)式參數(shù)、三個(gè)傳值參數(shù)的構(gòu)造函數(shù)
public ExpressionAnalyze(String expr,double value1,double value2,double value3)
throws Exception
{
this.expr = expr;
numOfParameter = 3;
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
try{
clearBlank();
seekOutElem();
compute();
}
catch (Exception e){
throw new Exception(e.toString());
}
}
//清除expr中的空格
private void clearBlank() throws Exception{
//清除expr末尾的空格
expr = expr.trim();
char [] exprArray = new char[expr.length()];
//將expr中的元素復(fù)制到數(shù)組exprArray中
for(int i = expr.length()-1;i >= 0;i--)
exprArray[i] = expr.charAt(i);
//逐個(gè)將空格清除
for(int i = expr.length()-1;i >= 0;i--){
int j;
if(exprArray[i] ==' '){
j = i;
while(j < exprArray.length - 1){
exprArray[j] = exprArray[j + 1];
j++;
}
exprArray[exprArray.length - 1] = ' ';
}
}
//將數(shù)組形式轉(zhuǎn)換成StringBuffer形式
StringBuffer exprStrBuf = new StringBuffer("");
for(int i = 0;i < exprArray.length;i++){
exprStrBuf.insert(i,exprArray[i]);
}
//將StringBuffer形式轉(zhuǎn)換成String形式
expr = exprStrBuf.toString().trim();
if(expr.length() == 0)
throw new Exception("the length of the expression is 0");
}
//將字符串中的變量、常量、運(yùn)算符挑出
private void seekOutElem() throws Exception{
int minLocation;
int startPoint = 0;
boolean isKeyword;
do{
minLocation = expr.length();
isKeyword = false;
for(int i = 0;i < keywords.length;i++) {
int kwdLocation = expr.substring(startPoint).indexOf(keywords[i]);
if(kwdLocation == -1)
kwdLocation = expr.length();
else
kwdLocation += startPoint;
//如果是運(yùn)算符
if(kwdLocation == startPoint &&
(keywords[i].equals("(") ||
keywords[i].length() == 1 ||
expr.charAt(startPoint + keywords[i].length()) == '('
)
)
{
//如果鏈表為空
if(elemList == null){
elemList = new ElemList (keywords[i]);
current = elemList;
current.isOperator = true;
}
//如果鏈表不空
else{
current.next = new ElemList (keywords[i]);
current = current.next;
current.isOperator = true;
}
isKeyword = true;
break;
}
if(minLocation > kwdLocation)
minLocation = kwdLocation;
}
//如果不是運(yùn)算符
if(!isKeyword){
//如果鏈表為空
if(elemList == null){
elemList = new ElemList (expr.substring(startPoint,minLocation));
current = elemList;
current.isOperator = false;
}
//如果鏈表不空
else{
current.next = new ElemList (expr.substring(startPoint,minLocation));
current = current.next;
current.isOperator = false;
}
}
startPoint += current.data.length();
}while(startPoint < expr.length());
//公式末尾添加"#"
current.next = new ElemList ("#");
current = current.next;
current.isOperator = true;
}
//計(jì)算最終的結(jié)果
private void compute() throws Exception{
//處理公式開頭的負(fù)號(hào)
if(elemList.data.equals("-")){
ElemList temp = new ElemList ("0");
temp.next = elemList;
elemList = temp;
}
for(current = elemList;current.next != null;current = current.next){
//處理負(fù)號(hào)
if(current.data.equals("(") && current.next.data.equals("-")){
ElemList temp = new ElemList ("0");
temp.next = current.next;
current.next = temp;
}
//處理常量自然對(duì)數(shù)的底 e
else if(current.data.equals("E"))
current.data = (new Double(Math.E)).toString();
//處理常量圓周率
else if(current.data.equals("PI"))
current.data = (new Double(Math.PI)).toString();
}
//找出公式中的變量,并對(duì)其恰當(dāng)?shù)馁x值
boolean findFirst = false , findSecond = false,findThird = false;
switch(numOfParameter){
case 0 :
for(current = elemList;current != null;current = current.next)
if(!current.isOperator){
//強(qiáng)制類型轉(zhuǎn)換,若轉(zhuǎn)換不成功則說明是變量
try{
Double.parseDouble(current.data);
}
catch (NumberFormatException e){
throw new Exception ("the variable '" + current.data
+ "' needs a value");
}
}
break;
case 1 :
for(current = elemList;current != null;current = current.next)
if(!current.isOperator){
//強(qiáng)制類型轉(zhuǎn)換,若轉(zhuǎn)換不成功則說明是變量
try{
Double.parseDouble(current.data);
}
catch (NumberFormatException e){
findFirst = true;
firstStr = new String(current.data);
firstDou = value1;
break;
}
}
if(!findFirst)
throw new Exception ("there is no variable,the value '" + value1
+"' is not needed");
break;
case 2 :
for(current = elemList;current != null;current = current.next)
if(!current.isOperator){
//強(qiáng)制類型轉(zhuǎn)換,若轉(zhuǎn)換不成功則說明是變量
try{
Double.parseDouble(current.data);
}
catch (NumberFormatException e){
findFirst = true;
firstStr = new String(current.data);
firstDou = value1;
break;
}
}
if(!findFirst)
throw new Exception ("there is no variable,the value '" + value1
+"' is not needed");
for(;current != null;current = current.next)
if(!current.isOperator && !current.data.equals(firstStr)){
//強(qiáng)制類型轉(zhuǎn)換,若轉(zhuǎn)換不成功則說明是變量
try{
Double.parseDouble(current.data);
}
catch (NumberFormatException e){
findSecond = true;
secondStr = new String(current.data);
secondDou = value2;
break;
}
}
if(!findSecond)
throw new Exception ("there are not so much variables,the value '"
+ value2 + "' is not needed");
break;
case 3 :
for(current = elemList;current != null;current = current.next)
if(!current.isOperator){
//強(qiáng)制類型轉(zhuǎn)換,若轉(zhuǎn)換不成功則說明是變量
try{
Double.parseDouble(current.data);
}
catch (NumberFormatException e){
findFirst = true;
firstStr = new String(current.data);
firstDou = value1;
break;
}
}
if(!findFirst)
throw new Exception ("there is no variable,the value '" + value1
+"' is not needed");
for(;current != null;current = current.next)
if(!current.isOperator && !current.data.equals(firstStr)){
//強(qiáng)制類型轉(zhuǎn)換,若轉(zhuǎn)換不成功則說明是變量
try{
Double.parseDouble(current.data);
}
catch (NumberFormatException e){
findSecond = true;
secondStr = new String(current.data);
secondDou = value2;
break;
}
}
if(!findSecond)
throw new Exception ("there are not so much variables,the value '"
+ value2 + "' is not needed");
for(;current != null;current = current.next)
if(!current.isOperator && !current.data.equals(firstStr)
&& !current.data.equals(secondStr)){
//強(qiáng)制類型轉(zhuǎn)換,若轉(zhuǎn)換不成功則說明是變量
try{
Double.parseDouble(current.data);
}
catch (NumberFormatException e){
findThird = true;
thirdStr = new String(current.data);
thirdDou = value3;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -