Open In App

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

Last Updated : 01 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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.

  • One approach involves using the ScriptEngine class from the javax.script package, which allows for the dynamic execution of scripts, including mathematical expressions written in languages like JavaScript.
  • Another approach involves the Stack data structure using which we can evaluate string mathematical expressions.

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:

  • Using ScriptEngineManager Class
  • Using Stack or logical method

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.

Java




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:

Console output

2. Using Stack or logical method

Java




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:

  • Java provides multiple methods for evaluating mathematical expressions given in string form.
  • The straightforward approach involves utilizing the ScriptEngine class from the javax.script package, leveraging its capability to dynamically evaluate expressions, particularly those in JavaScript.
  • Otherwise we can implement it using stack data structure.


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads