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: -10Example 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.
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);
}
} |
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.