Mathematics
Programming
String Processing
Evaluation Techniques
Problem Solving

How to evaluate a math expression given in string form?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Evaluating mathematical expressions provided in a string format is a common problem that is encountered in developing scientific calculators, parsing algorithms, or even within programming language compilers and interpreters. The main challenge involves correctly handling the order of operations, recognizing different types of numbers (like integers, decimals), and efficiently dealing with mathematical functions and operators.

Parsing and Tokenization

To evaluate a math expression from a string, the first step is to parse and tokenize the input. Parsing transforms the string (such as "2 + 3 * 4") into identifiable segments – namely numbers and operators.

  • Numbers: These could be integers or floats. Decimal points need careful handling to distinguish them from operators.
  • Operators: Includes +, -, *, /, and potentially more complex operators like ^ for exponentiation.
  • Parentheses: To handle expressions inside them with precedence.

Example of tokenization: For the string 3.5 + 4 * 2, the tokens would be [3.5, '+', 4, '*', 2].

Order of Operations (Operator Precedence and Associativity)

Operator precedence determines which operations are performed first in the absence of parentheses. Associativity dictates the order operations are performed in, left-to-right or right-to-left, when two operations have the same precedence level.

In common arithmetic:

  • * and / (multiplication and division) have higher precedence than + and - (addition and subtraction).
  • Operators of the same precedence are evaluated based on associativity; for addition and multiplication, this is typically left-to-right.

To correctly evaluate expressions, one can use the shunting-yard algorithm, invented by Edsger Dijkstra, which efficiently handles operator precedence and associativity by converting infix expressions (standard form) to postfix (Reverse Polish Notation - RPN).

Shunting-Yard Algorithm

This algorithm involves two main data structures:

  • Output Queue: Holds the tokens in postfix order.
  • Operator Stack: Temporarily holds operators and parentheses while the output queue is being populated.

Steps:

  1. Read tokens in order.
  2. If token is a number, add it to the output queue.
  3. If token is an operator, push it on the operator stack, but first remove any operators already on the operator stack that have greater or equal precedence and add them to the output queue.
  4. If a left parenthesis is encountered, push it onto the stack.
  5. If a right parenthesis is encountered, until the top of the stack is a left parenthesis, pop operators off the stack onto the output queue, then discard the left parenthesis.
  6. After the input is read, pop all remaining operators on the stack to the queue.

Evaluation of RPN

Once you have an expression in RPN, evaluating it is straightforward:

  1. While there are input tokens, read the next token from left to right.
  2. If the token is a value, push it onto the stack.
  3. If the token is an operator, pop the necessary number of values from the stack, perform the operation, and push the result back onto the stack.
  4. The result of the expression is the value left in the stack.

This method reliably handles complex mathematical expressions, including nested functions and mixed operations, by respecting the mathematical order of operations while maintaining reasonable computational efficiency.

Summary Table

StepTask Performed
TokenizationSplit input into numbers and operators
ParsingConvert infix to postfix using shunting-yard
Evaluating PostfixCompute result from RPN expression

In conclusion, evaluating a string mathematical expression involves careful consideration of syntax, the precedence of operators, and efficient parsing strategies. Implementations vary based on specific programming languages or applications, but the outlined strategy provides a foundational approach applicable in many scenarios, ensuring that mathematical expressions are evaluated correctly and consistently.


Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.