?? eval.java
字號:
package duyongyao.eval;
import java.lang.reflect.Method;
import java.util.Vector;
public class Eval implements IEval {
private boolean shouldContinue = true;
private Vector stackOpnd = null;
private Vector stackOptr = null;
private Vector checkStr = null;
private int numLength = 0;
public Eval() {
}
private String myTrimAndCheck(String str) throws Exception {
String temp = "";
shouldContinue = true;
for (int i = 0; i < str.length(); i++) {
char xChar = str.charAt(i);
if (xChar >= '0' && xChar <= '9' || xChar == '(' || xChar == ')'
|| xChar == '+' || xChar == '-' || xChar == '*'
|| xChar == '/' || xChar == '.') {
temp = temp + xChar;
} else if (xChar != ' ') {
temp = "";
shouldContinue = false;
throw new Exception("運算式格式錯誤!(無效符號“" + xChar + "”)");
}
}
return temp;
}
private String getNumber(String str) throws Exception {
String tempNumber = "";
numLength = 0;
int count = 0;
shouldContinue = true;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) >= '0' && str.charAt(i) <= '9'
|| str.charAt(i) == '.') {
if (str.charAt(i) == '.') {
count++;
}
if (count <= 1) {
tempNumber = tempNumber + str.charAt(i);
} else {
shouldContinue = false;
throw new Exception("運算式格式錯誤!(數字錯誤)");
}
numLength++;
} else {
break;
}
}
return tempNumber;
}
/**
* 四則運算
*
* @author 北大青鳥--杜永耀
* @param expression
* 表達式。不能包含數學函數,只能由數字、括號或基本運算符組成
* @return 表達式計算后的結果
* @throws Exception
*/
public double eval(String expression) throws Exception {
if (shouldContinue) {
stackOpnd = new Vector();
stackOptr = new Vector();
stackOptr.addElement('#');
checkStr = new Vector();
String tempStr = scientificExpressionToNormal("(" + expression
+ ")").replace("-(", "-1*(");
tempStr = myTrimAndCheck(tempStr);
while (tempStr.length() > 0) {
if (tempStr.charAt(0) == '('
&& (tempStr.charAt(1) != '+' && tempStr.charAt(1) != '-')
|| tempStr.charAt(0) == ')' || tempStr.charAt(0) == '+'
|| tempStr.charAt(0) == '-' || tempStr.charAt(0) == '*'
|| tempStr.charAt(0) == '/') {
checkStr.addElement(tempStr.charAt(0));
tempStr = tempStr.substring(1, tempStr.length());
} else if (tempStr.charAt(0) == '('
&& (tempStr.charAt(1) == '+' || tempStr.charAt(1) == '-')) {
checkStr.addElement(tempStr.charAt(0));
tempStr = tempStr.substring(1, tempStr.length());
if (tempStr.charAt(0) == '+') {
tempStr = tempStr.substring(1, tempStr.length());
checkStr.addElement(getNumber(tempStr));
tempStr = tempStr
.substring(numLength, tempStr.length());
} else if (tempStr.charAt(0) == '-') {
String tempStrNum = "-";
tempStr = tempStr.substring(1, tempStr.length());
tempStrNum = tempStrNum + getNumber(tempStr);
double tempDouble = Double.parseDouble(tempStrNum);
checkStr.addElement(tempDouble);
tempStr = tempStr
.substring(numLength, tempStr.length());
}
} else if (tempStr.charAt(0) >= '0' && tempStr.charAt(0) <= '9') {
checkStr.addElement(getNumber(tempStr));
tempStr = tempStr.substring(numLength, tempStr.length());
}
}
try {
while (checkStr.size() > 0) {
if (checkStr.get(0).toString().charAt(0) >= '0'
&& checkStr.get(0).toString().charAt(0) <= '9'
|| checkStr.get(0).toString().charAt(0) == '-'
&& checkStr.get(0).toString().length() > 1) {
stackOpnd.add(0, checkStr.get(0));
checkStr.removeElementAt(0);
} else {
switch (compareOptr(stackOptr.get(0).toString().charAt(
0), checkStr.get(0).toString().charAt(0))) {
case '<':
stackOptr.add(0, checkStr.get(0));
checkStr.removeElementAt(0);
break;
case '=':
stackOptr.removeElementAt(0);
checkStr.removeElementAt(0);
break;
case '>':
char theta = stackOptr.remove(0).toString().charAt(
0);
double b = Double.parseDouble(stackOpnd.remove(0)
.toString());
double a = Double.parseDouble(stackOpnd.remove(0)
.toString());
stackOpnd.add(0, operate(a, theta, b));
break;
}
}
}
shouldContinue = true;
return Double.parseDouble(stackOpnd.remove(0).toString());
} catch (Exception ex) {
throw new Exception("運算式格式錯誤!(邏輯錯誤)");
}
} else {
shouldContinue = true;
return 0.0;
}
}
private double operate(double a, char x, double b) {
switch (x) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
return 0.0;
}
private char compareOptr(char first, char second) {
switch (first) {
case '+':
switch (second) {
case '+':
return '>';
case '-':
return '>';
case '*':
return '<';
case '/':
return '<';
case '(':
return '<';
case ')':
return '>';
}
;
break;
case '-':
switch (second) {
case '+':
return '>';
case '-':
return '>';
case '*':
return '<';
case '/':
return '<';
case '(':
return '<';
case ')':
return '>';
}
;
break;
case '*':
switch (second) {
case '+':
return '>';
case '-':
return '>';
case '*':
return '>';
case '/':
return '>';
case '(':
return '<';
case ')':
return '>';
}
;
break;
case '/':
switch (second) {
case '+':
return '>';
case '-':
return '>';
case '*':
return '>';
case '/':
return '>';
case '(':
return '<';
case ')':
return '>';
}
;
break;
case '(':
switch (second) {
case '+':
return '<';
case '-':
return '<';
case '*':
return '<';
case '/':
return '<';
case '(':
return '<';
case ')':
return '=';
}
;
break;
case ')':
switch (second) {
case '+':
return '>';
case '-':
return '>';
case '*':
return '>';
case '/':
return '>';
case ')':
return '>';
}
;
break;
case '#':
return '<';
}
return 'x';
}
// 執行帶一個參數的數學函數
private String getPartResultWithOneParameter(String expression,
String functionName) throws Exception {
String result = null;
// 調用數學函數
Method[] m = Math.class.getMethods();
for (int i = 0; i < m.length; i++) {
if (m[i].getName().equals(functionName)
&& m[i].getReturnType().getName().toLowerCase().equals(
"double")) {
result = m[i].invoke(null,
new Object[] { Double.parseDouble(expression) })
.toString();
break;
}
}
return "(" + result + ")";
}
// 執行帶兩個參數的數學函數
private String getPartResultWithTwoParameter(String expression,
String functionName) throws Exception {
String result = null;
String[] tempParameters = expression.replace(" ", "").split(",");
double[] parameters = new double[2];
parameters[0] = Double.parseDouble(tempParameters[0]);
parameters[1] = Double.parseDouble(tempParameters[1]);
// 調用數學函數
Method[] m = Math.class.getMethods();
for (int i = 0; i < m.length; i++) {
if (m[i].getName().equals(functionName)
&& m[i].getReturnType().getName().toLowerCase().equals(
"double")) {
result = m[i].invoke(null,
new Object[] { parameters[0], parameters[1] })
.toString();
break;
}
}
return "(" + result + ")";
}
// 拆分表達式為三部分:以某數學函數為界,分為函數前,參數,函數后
private String[] splitStr(String expression, String functionName)
throws Exception {
String[] result = new String[3];
int tempIntB = expression.indexOf(functionName);
int beginPosition = -1;
int endPosition = -1;
// 確定三部分各自的范圍
if (tempIntB >= 0) {
beginPosition = expression.indexOf("(", tempIntB);
int counter = 0;
for (int i = beginPosition; i < expression.length(); i++) {
if (expression.charAt(i) == '(') {
counter++;
} else if (expression.charAt(i) == ')') {
counter--;
}
if (counter == 0) {
endPosition = i;
break;
}
}
}
// 生成“函數前”、“參數”、“函數后”
result[0] = tempIntB == 0 ? "" : expression.substring(0, tempIntB);
result[1] = expression.substring(beginPosition + 1, endPosition);
result[2] = expression.substring(endPosition + 1);
return result;
}
private String getMathFunctionName(String expression) {
// 一個參數的函數
if (expression.indexOf("abs") >= 0) {
return "abs";
}
if (expression.indexOf("acos") >= 0) {
return "acos";
}
if (expression.indexOf("asin") >= 0) {
return "asin";
}
if (expression.indexOf("atan") >= 0) {
return "atan";
}
if (expression.indexOf("cbrt") >= 0) {
return "cbrt";
}
if (expression.indexOf("ceil") >= 0) {
return "ceil";
}
if (expression.indexOf("cos") >= 0) {
return "cos";
}
if (expression.indexOf("cosh") >= 0) {
return "cosh";
}
if (expression.indexOf("exp") >= 0) {
return "exp";
}
if (expression.indexOf("expm1") >= 0) {
return "expm1";
}
if (expression.indexOf("floor") >= 0) {
return "floor";
}
if (expression.indexOf("log") >= 0 || expression.indexOf("ln") >= 0) {
return "log";
}
if (expression.indexOf("log10") >= 0) {
return "log10";
}
if (expression.indexOf("log1p") >= 0) {
return "log1p";
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -