2Brute2Best
🔥0
02

Expression evaluation (Stack Sub-pattern)

Numbers wait on a stack until their operator can be applied. * and / apply at once; + and - wait to be summed. A ( saves the current result and sign and starts a fresh level.

Signals in the problem statement
  • ›

    evaluate a string like 3+2*2 or 1-(2+3)

  • ›

    Reverse Polish Notation tokens

  • ›

    operator precedence, unary minus, spaces

What makes it different

RPN is the easy one: the order is already decided, an operator just pops two numbers. Calculator II has precedence but no parentheses: keep the previous operator. Calculator has parentheses: push (result, sign) on ( and restore on ).

Questions

ordered from “learn the idea” to “recognise it without help”
  1. 1
    Evaluate Reverse Polish Notation
    Basic Anchor·LeetCode #150
    Medium
  2. 2
    Basic Calculator II
    Slight Variation·LeetCode #227
    Medium
  3. 3
    Basic Calculator
    Interview-Level·LeetCode #224
    Hard

Template

expression-template.cpp
// + - * / with precedence, no parentheses (Basic Calculator II).
// When a number is finished, apply the operator that came BEFORE it.
int calculate(string s) {
    vector<long long> st;                            // terms waiting to be added
    long long num = 0;
    char op = '+';                                   // pretend the string starts with '+'
    for (int i = 0; i <= (int)s.size(); i++) {
        char c = i < (int)s.size() ? s[i] : '+';     // fake '+' at the end flushes the last number
        if (isdigit(c)) { num = num * 10 + (c - '0'); continue; }
        if (c == ' ') continue;
        if (op == '+') st.push_back(num);
        else if (op == '-') st.push_back(-num);
        else if (op == '*') st.back() *= num;        // * and / bind to the latest term now
        else st.back() /= num;
        op = c;
        num = 0;
    }
    long long sum = 0;
    for (long long t : st) sum += t;                 // only + is left
    return (int)sum;
}
Remember this · Stack
Trigger
Matching pairs, nested structure, undo, evaluating expressions, "the last one wins".
Think
Does each new element need to look at the most recent unresolved element?
Key question
What does an item on the stack represent, and when does it get resolved?