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();
}
}
}
Nếu một trang web có nhiều hình ảnh, chúng sẽ được trình duyệt tải về từ từ, tải được đến đâu hiển thị đến đó. Ok, nhưng nếu chúng ta ko muốn người dùng tương tác với hình ảnh trước khi chúng được tải về đầy đủ thì sao? Cách giải quyết là đầu tiên chỉ hiện lên màn hình "Loading…", đồng thời tiến hành tải ảnh vào bộ đệm của trình duyệt, sau khi tải xong thì mới cho hiện lên trang web đầy đủ.


Recent Comments