87 lines
1.8 KiB
Java
87 lines
1.8 KiB
Java
|
import javax.script.*;
|
||
|
import java.util.LinkedList;
|
||
|
|
||
|
public class ExpressionParserShuntingYard {
|
||
|
|
||
|
static boolean isDelim(char c) {
|
||
|
return c == ' ';
|
||
|
}
|
||
|
|
||
|
static boolean isOperator(char c) {
|
||
|
return c == '+' || c == '-' || c == '*' || c == '/' || c == '%';
|
||
|
}
|
||
|
|
||
|
static int priority(char op) {
|
||
|
switch (op) {
|
||
|
case '+':
|
||
|
case '-':
|
||
|
return 1;
|
||
|
case '*':
|
||
|
case '/':
|
||
|
case '%':
|
||
|
return 2;
|
||
|
default:
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void processOperator(LinkedList<Integer> st, char op) {
|
||
|
int r = st.removeLast();
|
||
|
int l = st.removeLast();
|
||
|
switch (op) {
|
||
|
case '+':
|
||
|
st.add(l + r);
|
||
|
break;
|
||
|
case '-':
|
||
|
st.add(l - r);
|
||
|
break;
|
||
|
case '*':
|
||
|
st.add(l * r);
|
||
|
break;
|
||
|
case '/':
|
||
|
st.add(l / r);
|
||
|
break;
|
||
|
case '%':
|
||
|
st.add(l % r);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int eval(String s) {
|
||
|
LinkedList<Integer> st = new LinkedList<>();
|
||
|
LinkedList<Character> op = new LinkedList<>();
|
||
|
for (int i = 0; i < s.length(); i++) {
|
||
|
char c = s.charAt(i);
|
||
|
if (isDelim(c))
|
||
|
continue;
|
||
|
if (c == '(')
|
||
|
op.add('(');
|
||
|
else if (c == ')') {
|
||
|
while (op.getLast() != '(')
|
||
|
processOperator(st, op.removeLast());
|
||
|
op.removeLast();
|
||
|
} else if (isOperator(c)) {
|
||
|
while (!op.isEmpty() && priority(c) <= priority(op.getLast()))
|
||
|
processOperator(st, op.removeLast());
|
||
|
op.add(c);
|
||
|
} else {
|
||
|
String operand = "";
|
||
|
while (i < s.length() && Character.isDigit(s.charAt(i)))
|
||
|
operand += s.charAt(i++);
|
||
|
--i;
|
||
|
st.add(Integer.parseInt(operand));
|
||
|
}
|
||
|
}
|
||
|
while (!op.isEmpty())
|
||
|
processOperator(st, op.removeLast());
|
||
|
return st.get(0);
|
||
|
}
|
||
|
|
||
|
public static void main(String[] args) throws Exception {
|
||
|
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
|
||
|
|
||
|
String exp = "1+2*3*4+3*(2+2)-100";
|
||
|
System.out.println(eval(exp));
|
||
|
System.out.println((Integer) engine.eval(exp) == eval(exp));
|
||
|
}
|
||
|
}
|