Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class ExpressionEvaluator {
- String expression;
- boolean valid;
- ExpressionEvaluator left, right, entire;
- int lastOperatorPos;
- char lastOperatorChar;
- public ExpressionEvaluator(String expression) {
- this.expression = expression;
- valid = true;
- calc();
- }
- int priority(char c, boolean unary) {
- if (unary && (c == '-' || c == '+'))
- return 1;
- if (c == '^')
- return 2;
- if (c == '-' || c == '+')
- return 4;
- if (c == '*' || c == '/')
- return 3;
- return 0;
- }
- boolean validSymbols(String s) {
- for (int i = 0; i < s.length(); i++) {
- boolean ok = false;
- char c = s.charAt(i);
- if (c >= '0' && c <= '9')
- ok = true;
- if (c == '*' || c == '-' || c == '/' || c == '+' || c == '^')
- ok = true;
- if (c == '.')
- ok = true;
- if (c == '(' || c == ')')
- ok = true;
- if (c == 'x')
- ok = true;
- if (!ok)
- return false;
- }
- return true;
- }
- boolean isUnary(int i) {
- char c = expression.charAt(i);
- if (!(c == '+' || c == '-' || c == '*' || c == '/'))
- return false;
- boolean unary = false;
- if (i == 0) {
- unary = true;
- } else {
- char c1 = expression.charAt(i - 1);
- if (c1 == '(' || c1 == '-' || c1 == '+' || c1 == '*'
- || c1 == '/')
- unary = true;
- }
- return unary;
- }
- public BigDecimal evaluate(double valX) {
- if (!valid)
- throw new ArithmeticException();
- BigDecimal res = null;
- if (lastOperatorPos == -1) {
- if (entire != null) {
- res = entire.evaluate(valX);
- } else {
- if (expression.equals("x"))
- res = BigDecimal.valueOf(valX);
- else {
- try {
- double x = Double.parseDouble(expression);
- res = BigDecimal.valueOf(x);
- } catch (NumberFormatException e) {
- throw new ArithmeticException(
- "Not valid expression");
- }
- }
- }
- } else {
- BigDecimal leftVal = BigDecimal.ZERO, rightVal = BigDecimal.ZERO;
- if (lastOperatorChar == '+') {
- if (left.expression.length() != 0)
- leftVal = left.evaluate(valX);
- rightVal = right.evaluate(valX);
- res = leftVal.add(rightVal);
- }
- if (lastOperatorChar == '-') {
- if (left.expression.length() != 0)
- leftVal = left.evaluate(valX);
- rightVal = right.evaluate(valX);
- res = leftVal.subtract(rightVal);
- }
- if (lastOperatorChar == '*') {
- leftVal = left.evaluate(valX);
- rightVal = right.evaluate(valX);
- res = leftVal.multiply(rightVal);
- }
- if (lastOperatorChar == '/') {
- leftVal = left.evaluate(valX);
- rightVal = right.evaluate(valX);
- if (rightVal.equals(BigDecimal.ZERO))
- throw new ArithmeticException("Division by zero");
- res = leftVal.divide(rightVal, MathContext.DECIMAL128);
- }
- if (lastOperatorChar == '^') {
- leftVal = left.evaluate(valX);
- rightVal = right.evaluate(valX);
- if (Math.abs(rightVal.intValue() - rightVal.doubleValue()) < 1e-3)
- res = leftVal.pow(rightVal.intValue());
- else
- res = BigDecimal.valueOf(Math.pow(
- leftVal.doubleValue(), rightVal.doubleValue()));
- }
- }
- return res;
- }
- public double evaluateDouble(double valX) {
- if (!valid)
- throw new ArithmeticException();
- double res = 0;
- if (lastOperatorPos == -1) {
- if (entire != null) {
- res = entire.evaluateDouble(valX);
- } else {
- if (expression.equals("x"))
- res = valX;
- else {
- try {
- double x = Double.parseDouble(expression);
- res = x;
- } catch (NumberFormatException e) {
- throw new ArithmeticException(
- "Not valid expression");
- }
- }
- }
- } else {
- double leftVal = 0, rightVal = 0;
- if (lastOperatorChar == '+') {
- if (left.expression.length() != 0)
- leftVal = left.evaluateDouble(valX);
- rightVal = right.evaluateDouble(valX);
- res = leftVal + rightVal;
- }
- if (lastOperatorChar == '-') {
- if (left.expression.length() != 0)
- leftVal = left.evaluateDouble(valX);
- rightVal = right.evaluateDouble(valX);
- res = leftVal - rightVal;
- }
- if (lastOperatorChar == '*') {
- leftVal = left.evaluateDouble(valX);
- rightVal = right.evaluateDouble(valX);
- res = leftVal * rightVal;
- }
- if (lastOperatorChar == '/') {
- leftVal = left.evaluateDouble(valX);
- rightVal = right.evaluateDouble(valX);
- if (rightVal == 0)
- throw new ArithmeticException("Division by zero");
- res = leftVal / rightVal;
- }
- if (lastOperatorChar == '^') {
- leftVal = left.evaluateDouble(valX);
- rightVal = right.evaluateDouble(valX);
- res = Math.pow(leftVal, rightVal);
- }
- }
- return res;
- }
- public void calc() {
- if (expression == null || expression.length() == 0) {
- valid = false;
- return;
- }
- if (!validSymbols(expression)) {
- valid = false;
- return;
- }
- int len = expression.length();
- int[] rightBracket = new int[len];
- Arrays.fill(rightBracket, -1);
- ArrayList<Integer> leftBrackets = new ArrayList<Integer>();
- for (int i = 0; i < len; i++) {
- if (expression.charAt(i) == '(') {
- leftBrackets.add(i);
- }
- if (expression.charAt(i) == ')') {
- if (leftBrackets.size() == 0) {
- valid = false;
- return;
- }
- rightBracket[leftBrackets.get(leftBrackets.size() - 1)] = i;
- leftBrackets.remove(leftBrackets.size() - 1);
- }
- }
- if (leftBrackets.size() != 0) {
- valid = false;
- return;
- }
- for (int i = 1; i < len; i++)
- if (isUnary(i) && isUnary(i - 1)) {
- valid = false;
- return;
- }
- lastOperatorPos = -1;
- int operatorPriority = 0;
- for (int i = 0; i < len; i++) {
- if (expression.charAt(i) == '(')
- i = rightBracket[i];
- boolean unary = false;
- if (i == 0) {
- unary = true;
- } else {
- char c1 = expression.charAt(i - 1);
- if (c1 == '(' || c1 == '-' || c1 == '+' || c1 == '*'
- || c1 == '/')
- unary = true;
- }
- if (unary)
- continue;
- if (priority(expression.charAt(i), unary) != 0)
- if (priority(expression.charAt(i), unary) >= operatorPriority) {
- operatorPriority = priority(expression.charAt(i), unary);
- lastOperatorPos = i;
- }
- }
- int[] leftBracket = new int[len];
- for (int i = 0; i < len; i++)
- if (rightBracket[i] != -1)
- leftBracket[rightBracket[i]] = i;
- for (int i = len - 1; i >= 0; i--) {
- if (expression.charAt(i) == ')')
- i = leftBracket[i];
- boolean unary = false;
- if (i == 0) {
- unary = true;
- } else {
- char c1 = expression.charAt(i - 1);
- if (c1 == '(' || c1 == '-' || c1 == '+' || c1 == '*'
- || c1 == '/')
- unary = true;
- }
- if (!unary)
- continue;
- if (priority(expression.charAt(i), unary) != 0)
- if (priority(expression.charAt(i), unary) >= operatorPriority) {
- operatorPriority = priority(expression.charAt(i), unary);
- lastOperatorPos = i;
- }
- }
- if (operatorPriority == 2) {
- for (int i = len - 1; i >= 0; i--) {
- if (expression.charAt(i) == ')')
- i = leftBracket[i];
- if (expression.charAt(i) == '^')
- lastOperatorPos = i;
- }
- }
- if (lastOperatorPos == -1) {
- if (rightBracket[0] == len - 1) {
- entire = new ExpressionEvaluator(expression.substring(1,
- expression.length() - 1));
- } else {
- }
- } else {
- left = new ExpressionEvaluator(expression.substring(0,
- lastOperatorPos));
- right = new ExpressionEvaluator(expression.substring(
- lastOperatorPos + 1, expression.length()));
- lastOperatorChar = expression.charAt(lastOperatorPos);
- }
- }
- }
- String removeSpaces(String s) {
- ArrayList<Character> cc = new ArrayList<Character>();
- for (int i = 0; i < s.length(); i++)
- if (s.charAt(i) != ' ')
- cc.add(s.charAt(i));
- char[] ans = new char[cc.size()];
- for (int i = 0; i < cc.size(); i++)
- ans[i] = cc.get(i);
- return new String(ans);
- }
Advertisement
Add Comment
Please, Sign In to add comment