0

I am trying to read the sign from the arraylist, then do the expression for the two numbers before it and after it (for example, i-1 * i+1) . However the generated result is always either 5, 6 or 12! I cannot really find where the issue is within the code.

I am using arraylist because it is more dynamic than an array, in a sense that I can delete elements without caring about the length of the 'array'.

    String replaceStr = replacer.replace("+", " + ");

I am trying to add space in order to take the whole numbers as an element rather than using charAt which will not allow me to take a number that is more than one digit into the equation.

    Double Computing(String equation) {
    double result = 0.0;
    double multiplResult = 1.0; //

    String replacer = equation;

    String replaceStr = replacer.replace("+", " + ");
    String replaceStr1 = replaceStr.replace("x", " x ");
    String replaceStr2 = replaceStr1.replace("-", " - ");
    String replaceStr3 = replaceStr2.replace("/", " / ");
    String[] items = replaceStr3.split("\\s*");

    ArrayList<String> list = new ArrayList<String>((Arrays.asList(items)));




   for (int i = 0; i < list.size(); i++ ) {
       String NewNum;

       if (list.get(i) == "x" || list.get(i) == "/"){

           if(list.get(i) == "x") {
               NewNum = String.valueOf(Double.parseDouble(list.get(i - 1)) * Double.parseDouble(list.get(i + 1)));
               list.set(i, NewNum);
               list.remove(i-1);
               list.remove(i+1);
           }
           else if (list.get(i) == "/"){
               NewNum = String.valueOf(Double.parseDouble(list.get(i - 1)) / Double.parseDouble(list.get(i + 1)));
               list.set(i, NewNum);
               list.remove(i-1);
               list.remove(i+1);
           }
           multiplResult *= Double.parseDouble(list.get(0));
       }
       if (list.get(i) == "+" || list.get(i) == "-"){

           if(list.get(i) == "+") {
               NewNum = String.valueOf(Double.parseDouble(list.get(i - 1)) + Double.parseDouble(list.get(i + 1)));
               list.set(i, NewNum);
               list.remove(i-1);
               list.remove(i+1);
           }
           else if (list.get(i) == "-"){
               NewNum = String.valueOf(Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1)));
               list.set(i, NewNum);
               list.remove(i-1);
               list.remove(i+1);
           }
           multiplResult *= Double.parseDouble(list.get(0));
       }
       result += multiplResult;
    }
return result;
}
  • 2
    The usual data structure for parsing an arithmetic expression is a _stack_, not a list. And after that, you'll have to write a rudimentary parser. – Tim Biegeleisen Jul 24 '18 at 11:15
  • Or use the javascript engine and simply evaluate the equation. https://stackoverflow.com/a/11810784/829571 – assylias Jul 24 '18 at 11:19
  • 1
    @assylias better use a regex to constraint the equation to only the symbols allowed then. Otherwise whoever inputs the equation can easily abuse the program and let it be a huge security flaw. – kumesana Jul 24 '18 at 11:24
  • Or just use thirdparty libraries like JEXL or similar. – kumesana Jul 24 '18 at 11:26

2 Answers2

0

If you only use +, -, x and / and no brackets and the syntax of your equation is correct, then you can do it. But you must evaluate x and / first:

Double Computing(String equation) {
    String replace = equation.replace("+", " + ").replace("x", " x ").replace("-", " - ").replace("/", " / ");
    List<Object> list = new ArrayList<>(Arrays.asList(replace.split("\\s+")));

    for (int i = 0; i < list.size(); i++) {
        try {
            list.set(i, Double.parseDouble(list.get(i).toString()));
        } catch (NumberFormatException e) {
        }
    }

    while (list.contains("x")) {
        int i = list.indexOf("x");
        double mult = (Double) list.get(i - 1) * (Double) list.get(i + 1);
        list.remove(i + 1);
        list.set(i, mult);
        list.remove(i - 1);
    }
    while (list.contains("/")) {
        int i = list.indexOf("/");
        double div = (Double) list.get(i - 1) / (Double) list.get(i + 1);
        list.remove(i + 1);
        list.set(i, div);
        list.remove(i - 1);
    }
    double sum = (Double) list.get(0);
    for (int i = 1; i < (list.size() - 1); i += 2) {
        if (list.get(i).equals("+")) {
            sum += (Double) list.get(i + 1);
        } else {
            sum -= (Double) list.get(i + 1);
        }
    }

    return sum;
}
Ralf Renz
  • 1,061
  • 5
  • 7
0

Here is a simple evaluator:

public class Evaluator {
    private final char[] chars;
    private int pos;

    public static double evaluate(String expr) {
        return new Evaluator(expr).expression();
    }

    private Evaluator(String expr) {
        chars = expr.toCharArray();
    }

    private double expression() {
        double value = term();
        char op;
        while (skipSpaces() && ((op = chars[pos]) == '+' || op == '-')) {
            ++pos;
            double other = term();
            switch (op) {
                case '+':
                    value += other;
                    break;
                case '-':
                    value -= other;
                    break;
            }
        }
        return value;
    }

    private double term() {
        double value = factor();
        char op;
        while (skipSpaces() && ((op = chars[pos]) == 'x' || op == '/')) {
            ++pos;
            double other = factor();
            switch (op) {
                case 'x':
                    value *= other;
                    break;
                case '/':
                    value /= other;
                    break;
            }
        }
        return value;
    }

    private double factor() {
        if (skipSpaces() && chars[pos] == '(') {
            ++pos;
            double result = expression();
            if (skipSpaces() && chars[pos] == ')') {
                ++pos;
            }
            return result;
        }
        return number();
    }

    private double number() {
        if (!skipSpaces()) {
            return 0;
        }
        int start = pos;
        if (chars[pos] == '+' || chars[pos] == '-') {
            ++pos;
        }
        if (pos >= chars.length || !Character.isDigit(chars[pos])) {
            return 0;
        }
        do {
            ++pos;
        } while (pos < chars.length
                && (Character.isDigit(chars[pos]) || chars[pos] == '.'));
        return Double.parseDouble(new String(chars, start, pos-start));
    }

    private boolean skipSpaces() {
        while (pos < chars.length && Character.isWhitespace(chars[pos])) {
            ++pos;
        }
        return pos < chars.length;
    }
}
Maurice Perry
  • 9,261
  • 2
  • 12
  • 24