Question

I'm trying to solve simple string expressions e.g. 1+2*3/4, without brackets. I'm done with simple integer part, the above expression will work perfectly, but now i'm stuck with decimal values, for example 1.1/2.2*4.4 All i want is to push the whole decimal number into stack (double), i'm working on it for quite some time but not quite getting it, your help would be much appreciated. Current code is:

import java.util.Stack;
import java.text.DecimalFormat;

public class EvaluateString
{
    public static double evaluate(String expression)
    {
        char[] tokens = expression.toCharArray();
        DecimalFormat df = new DecimalFormat("#.##");

         // Stack for numbers: 'values'
        Stack<Double> values = new Stack<Double>();

        // Stack for Operators: 'ops'
        Stack<Character> ops = new Stack<Character>();

        for (int i = 0; i < tokens.length; i++)
        {
             // Current token is a whitespace, skip it
            if (tokens[i] == ' ')
                continue;

            // Current token is a number, push it to stack for numbers
            if (tokens[i] >= '0' && tokens[i] <= '9')
            {
                StringBuffer sbuf = new StringBuffer();
                // There may be more than one digits in number
                while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9')
                    sbuf.append(tokens[i++]);
                values.push(Double.parseDouble(sbuf.toString()));
            }

            // Current token is an operator.
            else if (tokens[i] == '+' || tokens[i] == '-' ||
                     tokens[i] == '*' || tokens[i] == '/')
            {
                // While top of 'ops' has same or greater precedence to current
                // token, which is an operator. Apply operator on top of 'ops'
                // to top two elements in values stack
                while (!ops.empty() && hasPrecedence(tokens[i], ops.peek()))
                  values.push(applyOp(ops.pop(), values.pop(), values.pop()));

                // Push current token to 'ops'.
                ops.push(tokens[i]);
            }
        }

        // Entire expression has been parsed at this point, apply remaining
        // ops to remaining values
        while (!ops.empty())
            values.push(applyOp(ops.pop(), values.pop(), values.pop()));

        // Top of 'values' contains result, return it
        return Double.parseDouble(df.format(Double.parseDouble(String.valueOf(values.pop()))));
    }

    // Returns true if 'op2' has higher or same precedence as 'op1',
    // otherwise returns false.
    public static boolean hasPrecedence(char op1, char op2)
    {
        if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-'))
            return false;
        else
            return true;
    }

    // A utility method to apply an operator 'op' on operands 'a' 
    // and 'b'. Return the result.
    public static double applyOp(char op, double b, double a)
    {
        switch (op)
        {
        case '+':
            return a + b;
        case '-':
            return a - b;
        case '*':
            return a * b;
        case '/':
            if (b == 0)
                throw new
                UnsupportedOperationException("Cannot divide by zero");
            return a / b;
        }
        return 0;
    }
}

There is going to be some change in the part where the values are getting pushed in the 'value' stack.

Was it helpful?

Solution 2

You have done ! Just more little change:

        while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9')

Needs to be replaced with

       while (i < tokens.length && (Character.isDigit(tokens[i]) || tokens[i] == '.'))

OTHER TIPS

Why code it yourself? There are many thirdtpaty alternatives:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top