Evaluate Precedence Expression With + And *#

Levels: level-4
Data structures: string, stack
Patterns: mark-and-sweep

Description#

  • Given a string expression containing:
    • non-negative integers (possibly multi-digit)
    • operators + and *
    • no parentheses
    • optional whitespace
  • Evaluate the expression and return the integer result.
  • Operator precedence: * is evaluated before +.

Examples#

1"2*3+4" -> 10
2"2*3+4*3" -> 18
3"12 + 3*4 + 5" -> 29

Python Solution#

 1def eval_plus_mul(expr: str) -> int:
 2    """
 3    Evaluate expression with non-negative integers and operators '+' and '*',
 4    respecting precedence of '*' over '+'.
 5
 6    Idea:
 7    - Keep a running `term` (the current multiplication chain).
 8    - When we hit '+', we add the finished `term` into `total` and start a new term.
 9    - When we hit '*', we keep multiplying into the same term.
10
11    Time:  O(n)
12    Space: O(1)
13    """
14    if expr is None:
15        return 0
16
17    s = expr.replace(" ", "")
18    if not s:
19        return 0
20
21    total = 0
22    term = 0          # current multiplication term
23    num = 0
24    op = '+'          # previous operator applied to `num` into `term`
25
26    for i, ch in enumerate(s):
27        if ch.isdigit():
28            num = num * 10 + (ord(ch) - ord('0'))
29
30        # If operator or end: apply previous op
31        if (not ch.isdigit()) or i == len(s) - 1:
32            if op == '+':
33                # term is complete; push it to total, start new term with num
34                total += term
35                term = num
36            elif op == '*':
37                term *= num
38            else:
39                raise ValueError(f"Unexpected operator: {op}")
40
41            op = ch
42            num = 0
43
44    return total + term