Search code examples
javastringrecursionsubstring

Evaluate string expression in Java with two numbers using recursion


I'm having a problem with multiplying a positive number with a negative number from a string expression.

If my expression is -4*5 then it returns -20 but if I put 4*-5 then it returns -5 instead of -20.

I did a bit of debugging and found that my substring only picked up the -5 but there was no number after the * operator so it returned 0.0

I thought of checking for the negative sign before the expression gets executed and determining whether it's a negative number or not. However, it did not as expected.

Could I please get some help?

if (expression.contains("-")) 
{
    int indexOfExpression = expression.lastIndexOf('-');
    String beforeMinus = expression.substring(indexOfExpression-1,indexOfExpression);
    if(beforeMinus.equals("*") || beforeMinus.equals("/")) 
    {
        double afterMinus = Double.parseDouble(expression.substring(indexOfExpression,indexOfExpression+2));
        return afterMinus;
    }else {
            double rhs = evaluate(expression.substring(indexOfExpression+1));
            return evaluate(expression.substring(0, indexOfExpression)) - rhs;
    }
} else if (expression.contains("*")) {
    int indexOfExpression = expression.lastIndexOf("*");
    Double rhs = evaluate(expression.substring(indexOfExpression + 1));;
    return evaluate(expression.substring(0, indexOfExpression)) *rhs;
}

This is what I currently have and the output is -5 instead of -20.


Solution

  • There are lots of errors in the code, so I think it makes more sense to answer from the perspective of how could this be done better rather than just debugging. I'll assume you want to perform a binary operation of two number seperated by one of the four operators +, -, *, /. The main difficulty is the ambiguity between - as an operator and - as a symbol for a negative number (in which case it's more like multiplication by -1 than subtraction). The following isn't meant to be a bullet-proof algorithm, but to give you an idea of a more structured approach to the problem.

    class Operator {
        public String op;
        public int index;
    }
    
    Operator findOperator(String expression) {
        // Assumes that 'expression' is a simple expression of the form:
        //      <number><op><number>
        // Find all instances of '+', '-', '*', '/'.
        // If '-' appears one or more times with another symbol, the other one is
        // the operator. If more than one '-' appears, determine which is the
        // operator based on position (e.g. can't be the operator at index zero).
        return new Operator(...);
    }
    
    double calculate(String op, String lhs, String rhs) {
        double left = Double.parseDouble(lhs);
        double right = Double.parseDouble(rhs);
        switch (op) {
        case "+":
            return left + right;
        // etc.
        }
    }
    
    double calculate(String expression) {
        Operator operator = findOperator(expression);
        return calculate(
                operator.op,
                expression.substring(0, operator.index),
                expression.substring(operator.index + 1));
    }