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