Jan 20
1 + 1 = ?
12*(16-(6-40/20)-7) + 5*(23-3*(7-2)) = ?
sqrt[pow[12*(16-(6-40/20)-7) + 5*(23-3*(7-2)),3]] = ?
package calexp;
public class CalculateExpression {
private static final String MSG = "Invalid Expression";
private static final String[] FUNCTION_LIST = {
"abs", "sqrt", "sin", "cos", "tan", "cotan", "log", "exp", "pow"
};
private static final int[] PARAMETER_NUMBER = {
1, 1, 1, 1, 1, 1, 1, 1, 2
};
public static double calculate(String exp) throws Exception {
int sepa = findSeparator(exp);
if (sepa == -1)
return calcuSingleExp(exp);
if (sepa == 0)
switch (exp.charAt(0)) {
case '+':
return calculate(exp.substring(1));
case '-':
return -calculate(exp.substring(1));
default:
throw new Exception(MSG);
}
double part1 = calculate(exp.substring(0, sepa));
double part2 = calculate(exp.substring(sepa + 1));
switch (exp.charAt(sepa)) {
case '+':
return part1 + part2;
case '-':
return part1 - part2;
case '*':
return part1 * part2;
default:
return part1 / part2;
}
}
private static double calcuSingleExp(String exp) throws Exception {
exp = exp.trim();
if (exp.isEmpty()) throw new Exception(MSG);
int len = exp.length();
if (exp.charAt(len - 1) == ')') {
if (len < 3 || findOpen(exp, len - 1) != 0)
throw new Exception(MSG);
return calculate(exp.substring(1, len - 1));
}
try {
return Double.valueOf(exp);
} catch (NumberFormatException e) {
if (exp.charAt(len - 1) != ']') throw new Exception(MSG);
int open = findOpen(exp, len - 1);
String func = exp.substring(0, open).trim();
exp = exp.substring(open + 1, len - 1);
String[] sub = splitFay(exp);
int funcIndex = findFuncIndexOf(func);
if (funcIndex == -1) throw new Exception(MSG);
if (sub.length > PARAMETER_NUMBER[funcIndex]) throw new Exception(MSG);
double res = calculate(sub[0]);
switch (funcIndex) {
case 0: return Math.abs(res);
case 1: return Math.sqrt(res);
case 2: return Math.sin(res);
case 3: return Math.cos(res);
case 4: return Math.tan(res);
case 5: return 1.0 / Math.tan(res);
case 6: return Math.log(res);
case 7: return Math.exp(res);
default: return Math.pow(res, calculate(sub[1]));
}
}
}
private static int findFuncIndexOf(String func) {
for (int i = 0; i < FUNCTION_LIST.length; i++)
if (FUNCTION_LIST[i].equalsIgnoreCase(func))
return i;
return -1;
}
private static String[] splitFay(String listExp) throws Exception {
java.util.ArrayList<String> listSub = new java.util.ArrayList<String>();
char ch;
int j = 0;
for (int i = listExp.length() - 1; i >= 0; i--) {
ch = listExp.charAt(i);
if (ch == ')' || ch == ']')
i = findOpen(listExp, i);
else if (ch == ',') {
listSub.add(listExp.substring(j, i));
j = i + 1;
}
}
listSub.add(listExp.substring(j, listExp.length()));
String[] s = new String[listSub.size()];
for (j = 0; j < s.length; j++)
s[j] = listSub.get(j);
return s;
}
private static int findSeparator(String exp) throws Exception {
int len = exp.length();
if (isOperator(exp.charAt(len - 1)))
throw new Exception(MSG);
int i, j = -1;
char ch;
for (i = len - 1; i >= 0; i--) {
ch = exp.charAt(i);
if (ch == ')' || ch == ']') {
i = findOpen(exp, i);
if (i == -1)
throw new Exception(MSG);
} else if (ch == '+' || ch == '-') {
return i;
} else if (ch == '*' || ch == '/') {
j = i;
}
}
return j;
}
private static boolean isOperator(char ch) {
return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}
private static int findOpen(String exp, int off) throws Exception {
int count = 0;
char close = exp.charAt(off);
char open = close == ')' ? '(' : '[';
while (off >= 0) {
if (exp.charAt(off) == close) {
count++;
} else if (exp.charAt(off) == open) {
count--;
if (count == 0) return off;
}
off--;
}
throw new Exception(MSG);
}
public static void main(String[] args) {
try {
String s = "12*(16-(6-40/20)-7) + 5*(23-3*(7-2))";
System.out.println(calculate(s));
s = "sqrt[pow[12*(16-(6-40/20)-7) + 5*(23-3*(7-2)),3]]";
System.out.println(calculate(s));
s = "abs[cotan[sin[(5*(13-7)- (5*6-9)*2)+pow[2,3]*(sqrt[9*pow[9.13,2.2]]-8+12*cos[23])]-log[4]]]";
System.out.println(calculate(s));
s = "(1 * (4 + 50)) / 69";
System.out.println(calculate(s));
} catch (Exception e) {
e.printStackTrace();
}
}
}

Recent Comments