Parse simple math expression
This task use java to parse simple math expression.
Parse simple math expression
- Create Formula class as following
- Call Formula.calculate() method as following
Call Formula.calculate() method
Map<String, Object> data = new HashMap<String, Object>();
data.put("a", 2);
data.put("b", 3);
String formula = "a - b * a";
Object result = Formula.calculate(data, formula);
if (result != null) {
logger.info(result.toString());
} else {
logger.info("NULL");
}
Formula class
public static class Formula {
private Map<String, Object> data;
private String formula;
public Formula(Map<String, Object> data, String formula) {
this.data = data;
this.formula = formula;
}
public static Object calculate(Map<String, Object> data, String formula) {
return new Formula(data, formula).calculate();
}
public Object calculate() {
int pos = lastOperator(formula, new String[] { "+", "-" });
if (pos < 0) {
pos = lastOperator(formula, new String[] { "*", "/" });
if (pos < 0) {
return calculate(formula);
} else {
return calculate(formula.substring(0, pos).trim(), formula.charAt(pos) + "", formula.substring(pos + 1).trim());
}
} else {
return calculate(formula.substring(0, pos).trim(), formula.charAt(pos) + "", formula.substring(pos + 1).trim());
}
}
private Object calculate(String leftSide, String operator, String rightSide) {
Object valLeft = null;
Object valRight = null;
int pos = lastOperator(leftSide, new String[] { "+", "-" });
if (pos < 0) {
pos = lastOperator(leftSide, new String[] { "*", "/" });
if (pos < 0) {
valLeft = calculate(leftSide);
} else {
valLeft = calculate(leftSide.substring(0, pos).trim(), leftSide.charAt(pos) + "", leftSide.substring(pos + 1).trim());
}
} else {
valLeft = calculate(leftSide.substring(0, pos).trim(), leftSide.charAt(pos) + "", leftSide.substring(pos + 1).trim());
}
pos = lastOperator(rightSide, new String[] { "*", "/" });
if (pos < 0) {
valRight = calculate(rightSide);
} else {
valRight = calculate(rightSide.substring(0, pos).trim(), rightSide.charAt(pos) + "", rightSide.substring(pos + 1).trim());
}
return calculate(valLeft, operator, valRight);
}
private Object calculate(Object leftSide, String operator, Object rightSide) {
Object tag = null;
if (leftSide == null || rightSide == null) return null;
if (isNumber(leftSide) && isNumber(rightSide)) {
double valLeft = parseNumber(leftSide);
double valRight = parseNumber(rightSide);
tag = calculate(valLeft, operator, valRight);
} else if (isString(leftSide) || isString(rightSide)) {
if ("+".equals(operator)) {
tag = leftSide.toString() + rightSide.toString();
}
}
return tag;
}
private Object calculate(double leftSide, String operator, double rightSide) {
if ("+".equals(operator)) {
return leftSide + rightSide;
} else if ("-".equals(operator)) {
return leftSide - rightSide;
} else if ("*".equals(operator)) {
return leftSide * rightSide;
} else if ("/".equals(operator) && rightSide != 0) {
return leftSide / rightSide;
} else {
return null;
}
}
private double parseNumber(Object src) {
double tag = 0;
try {
tag = Double.parseDouble(src.toString());
} catch (Exception e) {
tag = 0;
}
return tag;
}
private boolean isString(Object src) {
String kind = src.getClass().getName();
if ("java.lang.String".equals(kind)) return true;
return false;
}
private boolean isNumber(Object src) {
if (src == null) return false;
String[] types = new String[] { "java.lang.Character", "java.lang.Byte", "java.lang.Short", "java.lang.Integer", "java.lang.Long", "java.lang.Float", "java.lang.Double" };
String kind = src.getClass().getName();
for (int i = 0; i < types.length; i++) {
if (types[i].equalsIgnoreCase(kind)) return true;
}
return false;
}
private Object calculate(String src) {
if (data.containsKey(src)) {
return data.get(src);
} else {
return null;
}
}
private int lastOperator(String src, String[] operators) {
int tag = -1;
for (int i = 0; i < operators.length; i++) {
int pos = src.lastIndexOf(operators[i]);
if (pos < 0) continue;
if (tag < 0) {
tag = pos;
} else {
if (pos > tag) {
tag = pos;
}
}
}
return tag;
}
}
No comments:
Post a Comment