Open In App

How to Evaluate Math Expression Given in String Form in Java?

Evaluating a mathematical expression given in string form is a common task in Java programming, often encountered in applications involving mathematical computations or user input processing.

Example of Evaluate String Expressions:

Example 1: Input String: “10-4*5”
Output: -10



Example 2: Input String: “3.5 + 2.8 * ( 4 – 1.2 ) / 2”
Output: 7.42

Program to Evaluate Math Expression Given in String Form in Java

There are certain methods to convert and evaluate a math expression given in string form in Java as mentioned below:



1. Using ScriptEngineManager Class

The Nashorn JavaScript script engine, its APIs, and its tool are deprecated in Java 11. Future iterations of Java will eliminate them. JDK 8 was the most current version to incorporate the Nashorn JavaScript engine.




import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.*;
  
public class GFG {
    public static void main(String[] args)
        throws ScriptException
    {
       // Create a ScriptEngineManager to manage script engines
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine
            = manager.getEngineByName("JavaScript");   // Retrieve a JavaScript engine from the manager
        String str = "10-4*5";    // Define a mathematical expression to evaluate
        System.out.println(engine.eval(str));
    }
}

Output:

Below is the output of the program in console:

2. Using Stack or logical method




import java.util.*;
import java.util.Stack;
  
public class Main {
  
    // Function to evaluate a mathematical expression given
    // in string form
    public static double
    evaluateExpression(String expression)
    {
        char[] tokens = expression.toCharArray();
  
        // Stacks to store operands and operators
        Stack<Double> values = new Stack<>();
        Stack<Character> operators = new Stack<>();
  
        // Iterate through each character in the expression
        for (int i = 0; i < tokens.length; i++) {
            if (tokens[i] == ' ')
                continue;
  
            // If the character is a digit or a decimal
            // point, parse the number
            if ((tokens[i] >= '0' && tokens[i] <= '9')
                || tokens[i] == '.') {
                StringBuilder sb = new StringBuilder();
                // Continue collecting digits and the
                // decimal point to form a number
                while (i < tokens.length
                       && (Character.isDigit(tokens[i])
                           || tokens[i] == '.')) {
                    sb.append(tokens[i]);
                    i++;
                }
                // Parse the collected number and push it to
                // the values stack
                values.push(
                    Double.parseDouble(sb.toString()));
                i--; // Decrement i to account for the extra
                     // increment in the loop
            }
            else if (tokens[i] == '(') {
                // If the character is '(', push it to the
                // operators stack
                operators.push(tokens[i]);
            }
            else if (tokens[i] == ')') {
                // If the character is ')', pop and apply
                // operators until '(' is encountered
                while (operators.peek() != '(') {
                    values.push(applyOperator(
                        operators.pop(), values.pop(),
                        values.pop()));
                }
                operators.pop(); // Pop the '('
            }
            else if (tokens[i] == '+' || tokens[i] == '-'
                     || tokens[i] == '*'
                     || tokens[i] == '/') {
                // If the character is an operator, pop and
                // apply operators with higher precedence
                while (!operators.isEmpty()
                       && hasPrecedence(tokens[i],
                                        operators.peek())) {
                    values.push(applyOperator(
                        operators.pop(), values.pop(),
                        values.pop()));
                }
                // Push the current operator to the
                // operators stack
                operators.push(tokens[i]);
            }
        }
  
        // Process any remaining operators in the stack
        while (!operators.isEmpty()) {
            values.push(applyOperator(operators.pop(),
                                      values.pop(),
                                      values.pop()));
        }
  
        // The result is the only remaining element in the
        // values stack
        return values.pop();
    }
  
    // Function to check if operator1 has higher precedence
    // than operator2
    private static boolean hasPrecedence(char operator1,
                                         char operator2)
    {
        if (operator2 == '(' || operator2 == ')')
            return false;
        return (operator1 != '*' && operator1 != '/')
            || (operator2 != '+' && operator2 != '-');
    }
  
    // Function to apply the operator to two operands
    private static double applyOperator(char operator,
                                        double b, double a)
    {
        switch (operator) {
        case '+':
            return a + b;
        case '-':
            return a - b;
        case '*':
            return a * b;
        case '/':
            if (b == 0)
                throw new ArithmeticException(
                    "Cannot divide by zero");
            return a / b;
        }
        return 0;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        String exp = "3.5 + 2.8 * ( 4 - 1.2 ) / 2";
        double result = evaluateExpression(exp);
        System.out.println("Result: " + result);
    }
}

Output
Result: 7.42



Illustration:


Article Tags :