qwerty787788

Expression evaluator

Feb 8th, 2013
266
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.98 KB | None | 0 0
  1. public class ExpressionEvaluator {
  2.         String expression;
  3.         boolean valid;
  4.         ExpressionEvaluator left, right, entire;
  5.         int lastOperatorPos;
  6.         char lastOperatorChar;
  7.  
  8.         public ExpressionEvaluator(String expression) {
  9.             this.expression = expression;
  10.             valid = true;
  11.             calc();
  12.         }
  13.  
  14.         int priority(char c, boolean unary) {
  15.             if (unary && (c == '-' || c == '+'))
  16.                 return 1;
  17.             if (c == '^')
  18.                 return 2;
  19.             if (c == '-' || c == '+')
  20.                 return 4;
  21.             if (c == '*' || c == '/')
  22.                 return 3;
  23.             return 0;
  24.         }
  25.  
  26.         boolean validSymbols(String s) {
  27.             for (int i = 0; i < s.length(); i++) {
  28.                 boolean ok = false;
  29.                 char c = s.charAt(i);
  30.                 if (c >= '0' && c <= '9')
  31.                     ok = true;
  32.                 if (c == '*' || c == '-' || c == '/' || c == '+' || c == '^')
  33.                     ok = true;
  34.                 if (c == '.')
  35.                     ok = true;
  36.                 if (c == '(' || c == ')')
  37.                     ok = true;
  38.                 if (c == 'x')
  39.                     ok = true;
  40.                 if (!ok)
  41.                     return false;
  42.             }
  43.             return true;
  44.         }
  45.  
  46.         boolean isUnary(int i) {
  47.             char c = expression.charAt(i);
  48.             if (!(c == '+' || c == '-' || c == '*' || c == '/'))
  49.                 return false;
  50.             boolean unary = false;
  51.             if (i == 0) {
  52.                 unary = true;
  53.             } else {
  54.                 char c1 = expression.charAt(i - 1);
  55.                 if (c1 == '(' || c1 == '-' || c1 == '+' || c1 == '*'
  56.                         || c1 == '/')
  57.                     unary = true;
  58.             }
  59.             return unary;
  60.         }
  61.  
  62.         public BigDecimal evaluate(double valX) {
  63.             if (!valid)
  64.                 throw new ArithmeticException();
  65.             BigDecimal res = null;
  66.             if (lastOperatorPos == -1) {
  67.                 if (entire != null) {
  68.                     res = entire.evaluate(valX);
  69.                 } else {
  70.                     if (expression.equals("x"))
  71.                         res = BigDecimal.valueOf(valX);
  72.                     else {
  73.                         try {
  74.                             double x = Double.parseDouble(expression);
  75.                             res = BigDecimal.valueOf(x);
  76.                         } catch (NumberFormatException e) {
  77.                             throw new ArithmeticException(
  78.                                     "Not valid expression");
  79.                         }
  80.                     }
  81.                 }
  82.             } else {
  83.                 BigDecimal leftVal = BigDecimal.ZERO, rightVal = BigDecimal.ZERO;
  84.                 if (lastOperatorChar == '+') {
  85.                     if (left.expression.length() != 0)
  86.                         leftVal = left.evaluate(valX);
  87.                     rightVal = right.evaluate(valX);
  88.                     res = leftVal.add(rightVal);
  89.                 }
  90.                 if (lastOperatorChar == '-') {
  91.                     if (left.expression.length() != 0)
  92.                         leftVal = left.evaluate(valX);
  93.                     rightVal = right.evaluate(valX);
  94.                     res = leftVal.subtract(rightVal);
  95.                 }
  96.                 if (lastOperatorChar == '*') {
  97.                     leftVal = left.evaluate(valX);
  98.                     rightVal = right.evaluate(valX);
  99.                     res = leftVal.multiply(rightVal);
  100.                 }
  101.                 if (lastOperatorChar == '/') {
  102.                     leftVal = left.evaluate(valX);
  103.                     rightVal = right.evaluate(valX);
  104.                     if (rightVal.equals(BigDecimal.ZERO))
  105.                         throw new ArithmeticException("Division by zero");
  106.                     res = leftVal.divide(rightVal, MathContext.DECIMAL128);
  107.                 }
  108.                 if (lastOperatorChar == '^') {
  109.                     leftVal = left.evaluate(valX);
  110.                     rightVal = right.evaluate(valX);
  111.                     if (Math.abs(rightVal.intValue() - rightVal.doubleValue()) < 1e-3)
  112.                         res = leftVal.pow(rightVal.intValue());
  113.                     else
  114.                         res = BigDecimal.valueOf(Math.pow(
  115.                                 leftVal.doubleValue(), rightVal.doubleValue()));
  116.                 }
  117.             }
  118.             return res;
  119.         }
  120.  
  121.         public double evaluateDouble(double valX) {
  122.             if (!valid)
  123.                 throw new ArithmeticException();
  124.             double res = 0;
  125.             if (lastOperatorPos == -1) {
  126.                 if (entire != null) {
  127.                     res = entire.evaluateDouble(valX);
  128.                 } else {
  129.                     if (expression.equals("x"))
  130.                         res = valX;
  131.                     else {
  132.                         try {
  133.                             double x = Double.parseDouble(expression);
  134.                             res = x;
  135.                         } catch (NumberFormatException e) {
  136.                             throw new ArithmeticException(
  137.                                     "Not valid expression");
  138.                         }
  139.                     }
  140.                 }
  141.             } else {
  142.                 double leftVal = 0, rightVal = 0;
  143.                 if (lastOperatorChar == '+') {
  144.                     if (left.expression.length() != 0)
  145.                         leftVal = left.evaluateDouble(valX);
  146.                     rightVal = right.evaluateDouble(valX);
  147.                     res = leftVal + rightVal;
  148.                 }
  149.                 if (lastOperatorChar == '-') {
  150.                     if (left.expression.length() != 0)
  151.                         leftVal = left.evaluateDouble(valX);
  152.                     rightVal = right.evaluateDouble(valX);
  153.                     res = leftVal - rightVal;
  154.                 }
  155.                 if (lastOperatorChar == '*') {
  156.                     leftVal = left.evaluateDouble(valX);
  157.                     rightVal = right.evaluateDouble(valX);
  158.                     res = leftVal * rightVal;
  159.                 }
  160.                 if (lastOperatorChar == '/') {
  161.                     leftVal = left.evaluateDouble(valX);
  162.                     rightVal = right.evaluateDouble(valX);
  163.                     if (rightVal == 0)
  164.                         throw new ArithmeticException("Division by zero");
  165.                     res = leftVal / rightVal;
  166.                 }
  167.                 if (lastOperatorChar == '^') {
  168.                     leftVal = left.evaluateDouble(valX);
  169.                     rightVal = right.evaluateDouble(valX);
  170.                     res = Math.pow(leftVal, rightVal);
  171.                 }
  172.             }
  173.             return res;
  174.         }
  175.  
  176.         public void calc() {
  177.             if (expression == null || expression.length() == 0) {
  178.                 valid = false;
  179.                 return;
  180.             }
  181.             if (!validSymbols(expression)) {
  182.                 valid = false;
  183.                 return;
  184.             }
  185.             int len = expression.length();
  186.             int[] rightBracket = new int[len];
  187.             Arrays.fill(rightBracket, -1);
  188.             ArrayList<Integer> leftBrackets = new ArrayList<Integer>();
  189.             for (int i = 0; i < len; i++) {
  190.                 if (expression.charAt(i) == '(') {
  191.                     leftBrackets.add(i);
  192.                 }
  193.                 if (expression.charAt(i) == ')') {
  194.                     if (leftBrackets.size() == 0) {
  195.                         valid = false;
  196.                         return;
  197.                     }
  198.                     rightBracket[leftBrackets.get(leftBrackets.size() - 1)] = i;
  199.                     leftBrackets.remove(leftBrackets.size() - 1);
  200.                 }
  201.             }
  202.             if (leftBrackets.size() != 0) {
  203.                 valid = false;
  204.                 return;
  205.             }
  206.             for (int i = 1; i < len; i++)
  207.                 if (isUnary(i) && isUnary(i - 1)) {
  208.                     valid = false;
  209.                     return;
  210.                 }
  211.             lastOperatorPos = -1;
  212.             int operatorPriority = 0;
  213.             for (int i = 0; i < len; i++) {
  214.                 if (expression.charAt(i) == '(')
  215.                     i = rightBracket[i];
  216.                 boolean unary = false;
  217.                 if (i == 0) {
  218.                     unary = true;
  219.                 } else {
  220.                     char c1 = expression.charAt(i - 1);
  221.                     if (c1 == '(' || c1 == '-' || c1 == '+' || c1 == '*'
  222.                             || c1 == '/')
  223.                         unary = true;
  224.                 }
  225.                 if (unary)
  226.                     continue;
  227.                 if (priority(expression.charAt(i), unary) != 0)
  228.                     if (priority(expression.charAt(i), unary) >= operatorPriority) {
  229.                         operatorPriority = priority(expression.charAt(i), unary);
  230.                         lastOperatorPos = i;
  231.                     }
  232.             }
  233.             int[] leftBracket = new int[len];
  234.             for (int i = 0; i < len; i++)
  235.                 if (rightBracket[i] != -1)
  236.                     leftBracket[rightBracket[i]] = i;
  237.             for (int i = len - 1; i >= 0; i--) {
  238.                 if (expression.charAt(i) == ')')
  239.                     i = leftBracket[i];
  240.                 boolean unary = false;
  241.                 if (i == 0) {
  242.                     unary = true;
  243.                 } else {
  244.                     char c1 = expression.charAt(i - 1);
  245.                     if (c1 == '(' || c1 == '-' || c1 == '+' || c1 == '*'
  246.                             || c1 == '/')
  247.                         unary = true;
  248.                 }
  249.                 if (!unary)
  250.                     continue;
  251.                 if (priority(expression.charAt(i), unary) != 0)
  252.                     if (priority(expression.charAt(i), unary) >= operatorPriority) {
  253.                         operatorPriority = priority(expression.charAt(i), unary);
  254.                         lastOperatorPos = i;
  255.                     }
  256.             }
  257.             if (operatorPriority == 2) {
  258.                 for (int i = len - 1; i >= 0; i--) {
  259.                     if (expression.charAt(i) == ')')
  260.                         i = leftBracket[i];
  261.                     if (expression.charAt(i) == '^')
  262.                         lastOperatorPos = i;
  263.                 }
  264.             }
  265.             if (lastOperatorPos == -1) {
  266.                 if (rightBracket[0] == len - 1) {
  267.                     entire = new ExpressionEvaluator(expression.substring(1,
  268.                             expression.length() - 1));
  269.                 } else {
  270.  
  271.                 }
  272.             } else {
  273.                 left = new ExpressionEvaluator(expression.substring(0,
  274.                         lastOperatorPos));
  275.                 right = new ExpressionEvaluator(expression.substring(
  276.                         lastOperatorPos + 1, expression.length()));
  277.                 lastOperatorChar = expression.charAt(lastOperatorPos);
  278.             }
  279.         }
  280.     }
  281.  
  282.     String removeSpaces(String s) {
  283.         ArrayList<Character> cc = new ArrayList<Character>();
  284.         for (int i = 0; i < s.length(); i++)
  285.             if (s.charAt(i) != ' ')
  286.                 cc.add(s.charAt(i));
  287.         char[] ans = new char[cc.size()];
  288.         for (int i = 0; i < cc.size(); i++)
  289.             ans[i] = cc.get(i);
  290.         return new String(ans);
  291.     }
Advertisement
Add Comment
Please, Sign In to add comment