[Java] 纯文本查看 复制代码
13 + 2 * (5 - 1) = 21.0
(12345 + 54321) * 10 = 666660.0
1 * (2 + 3) - 4 / (5 + 6) = 4.636363636363637
8.8 / ((5. - 3) * 2) * .1 = 0.22000000000000003
Exception in thread "main" java.lang.IllegalArgumentException: TODO index: 6
8888.8.8 + 1112
^
at org.cat73.eval.Eval.eval(Eval.java:22)
at org.cat73.eval.Eval.test(Eval.java:127)
at org.cat73.eval.Eval.main(Eval.java:135)
[Java] 纯文本查看 复制代码
package org.cat73.eval;
import java.util.Stack;
public class Eval {
public static double eval(String expression) {
Stack<Character> operatorStack = new Stack<>();
Stack<Double> numStack = new Stack<>();
StringBuilder numString = new StringBuilder();
boolean flag = false;
for(int i = 0; i < expression.length(); i++) {
char ch = expression.charAt(i);
if (ch == ' ') {
continue;
} else if (ch >= '0' && ch <= '9') {
numString.append(ch);
continue;
} else if (ch == '.') {
if(flag) {
throw new IllegalArgumentException(getThrowMsg(expression, i, "TODO index: %d", i));
} else {
numString.append(ch);
flag = true;
}
continue;
}
if(numString.length() > 0) {
numStack.push(Double.valueOf(numString.toString()));
numString = new StringBuilder();
flag = false;
}
switch(ch) {
case '(':
operatorStack.push(ch);
break;
case '*':
case '/':
case '+':
case '-':
loop:
while(!operatorStack.empty()) {
switch(operatorStack.peek()) {
case '(':
break loop;
case '*':
case '/':
case '+':
case '-':
if(getPriority(operatorStack.peek()) >= getPriority(ch)) {
numStack.push(calc(numStack.pop(), numStack.pop(), operatorStack.pop()));
} else {
break loop;
}
break;
}
}
operatorStack.push(ch);
break;
case ')':
while(!operatorStack.empty()) {
char operator = operatorStack.pop();
if(operator == '(') {
break;
} else {
numStack.push(calc(numStack.pop(), numStack.pop(), operator));
}
}
break;
default:
throw new IllegalArgumentException(getThrowMsg(expression, i, "Unknow operator: %c, index: %d", ch, i));
}
}
if(numString.length() > 0) {
numStack.push(Double.valueOf(numString.toString()));
}
while(!operatorStack.empty()) {
char operator = operatorStack.pop();
if(operator == '(') {
continue;
}
numStack.push(calc(numStack.pop(), numStack.pop(), operator));
}
return numStack.pop();
}
private static int getPriority(char operator) {
switch(operator) {
case '*':
case '/':
return 2;
case '+':
case '-':
return 1;
default:
throw new IllegalArgumentException("Unknow operator: " + operator);
}
}
private static double calc(double n2, double n1, char operator) {
switch(operator) {
case '+':
return n1 + n2;
case '-':
return n1 - n2;
case '*':
return n1 * n2;
case '/':
return n1 / n2;
default:
throw new IllegalArgumentException("Unknow operator: " + operator);
}
}
private static String getThrowMsg(String expression, int index, String msg, Object... objs) {
return String.format("%s\n%s\n%s", String.format(msg, objs), expression, String.format("%" + (index + 1) + "c", '^'));
}
private static void test(String expression) {
System.out.println(expression + " = " + eval(expression));
}
public static void main(String[] args) {
test("13 + 2 * (5 - 1)");
test("(12345 + 54321) * 10");
test("1 * (2 + 3) - 4 / (5 + 6)");
test("8.8 / ((5. - 3) * 2) * .1");
test("8888.8.8 + 1112");
}
}