Evaluating an expression with integers, +, and *, as well as -, / There is a job interview question, and the source of the question is here. 

The solution is pretty simple. We just need to split the input string by + and then by *. Then we compute products in a nested loop and sum up all the products.

public class Main {

    // http://www.careercup.com/question?id=4911380140392448
    public static void main(String[] args) {
        String equation = "1*5*4+8*9+16";
        int result = compute(equation);
        System.out.println(result);
    }

    static int compute(String equation) {
        int result = 0;
        String []byPluses = equation.split("\\+");
        for (String multipl : byPluses) {
            String []byMultipl = multipl.split("\\*");
            int multiplResult = 1;
            for (String operand : byMultipl) {
                multiplResult *= Integer.parseInt(operand);
            }
            result += multiplResult;
        }
        return result;
    }

}


But what if I was asked the following question after solving the initial problem:


  OK. What would you do if you needed to support not only + and * but also - and /?


The quick solution I thought up is this:

package careepcup.fb;

public class Main {

    // http://www.careercup.com/question?id=4911380140392448
    public static void main(String[] args) {
        // An equation with +, -, /, *
        String anotherEquation = "1*5*4+8*9+16/8-9"; // 85
        double another = computeAnother(anotherEquation);
        System.out.println(another);
    }

    static double computeAnother(String equation) {
        double result = 0.0;
        String noMinus = equation.replace("-", "+-");
        String[] byPluses = noMinus.split("\\+");

        for (String multipl : byPluses) {
            String[] byMultipl = multipl.split("\\*");
            double multiplResult = 1.0;
            for (String operand : byMultipl) {
                if (operand.contains("/")) {
                    String[] division = operand.split("\\/");
                    double divident = Double.parseDouble(division[0]);
                    for (int i = 1; i &lt; division.length; i++) {
                        divident /= Double.parseDouble(division[i]);
                    }
                    multiplResult *= divident;
                } else {
                    multiplResult *= Double.parseDouble(operand);
                }
            }
            result += multiplResult;
        }

        return result;
    }
}


What do think of my solution with -, +, /, *?
@tim has covered a bunch of what I was going to add, but here are some additional points:

You should anticipate having whitespace in the input. A "simple" replace-all would suffice:

equation = equation.replaceAll("\\s+", "");


Your solution of converting - to +- is novel, and effective, but it really should have a comment on it explaining that you are going to re-split the String and parse the new - as part of the integer, rather than as an operator. Leaving it as it is required some detective work on how it functions.

Bug: Your system will fail on things like: 1 + 2 * -3  (ignoring the whitespace).

Your inner workings of the * and / is a bit messy, though. A logical progression for your challenge would be to add, say, a % operator.... which would require a complicated change.

Operators of equal precedence should be handled together. treating * specially when compared to / makes it awkward because you have to test all combinations inside the * breakdown....

I would suggest using a smarter split expression, one that splits on the gaps between the operators and the values...:

String[] parts = operand.split("(?=[/*])|(?&lt;=[/*])");


With the above regex, you will get for example:

1/2*773 -&gt; [1, /, 2, *, 773]


The way the regex works is that it looks for two things (the regex is in two parts - using "lookaround" expressions)....


(?=[/*]) - A positive zero-width look-ahead - This says: find any gap between two characters where the next character is a / or *.
(?&lt;=[/*]) - A positive zero-width look-behind - This says: *find any gap between two characters where the previous character was a / or *.


Put them together with an or condition, it says: split the input on the gaps before and after / or *.
Now, you can just initialize the result to index-1, and then loop through the rest.... :

double result = Double.parseDouble(parts[0]);

for (int i = 1; i &lt; parts.length; i += 2) {
    String op = parts[i];
    double val = Double.parseDouble(parts[i+1]);
    switch (op) {
        case "*" :
            result *= val;
            break;
        case "/" :
            result /= val;
            break;
    }
}
return result;