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