data-structures · beginner · ~20 min

Are the brackets balanced?

Stack push/pop with a small alphabet; matching the right closer to the right opener.

Challenge

Implement int balanced_brackets(const char *s) returning 1 if the string s has correctly nested and matched brackets, else 0.

Bracket pairs recognised: (), [], {}.

All non-bracket characters are ignored.

Examples

balanced_brackets("()")           -> 1
balanced_brackets("(a + [b * c])")-> 1
balanced_brackets("{[()]}")       -> 1
balanced_brackets("(]")           -> 0   // mismatched closer
balanced_brackets("(")            -> 0   // unclosed
balanced_brackets(")")            -> 0   // closer with no opener
balanced_brackets("")             -> 1   // empty is balanced

Edge cases

  • Empty string is balanced (vacuously).
  • A closer without an opener is an immediate failure.
  • An opener never closed is a failure at end-of-string.

Why this matters

A stack-based bracket checker is the simplest non-trivial use of a stack and a great warm-up for full expression parsers. The same logic powers IDE bracket-matching, JSON validators, and shell quoting checkers.

Input format

Null-terminated string.

Output format

1/0.

Constraints

Use a stack (array). Maximum nesting depth assumed <= 512.

Starter code

int balanced_brackets(const char *s) { /* TODO */ return 0; }

Common mistakes

Just counting openers vs closers — fails on (]). Forgetting to check the stack is non-empty before peeking on a closer.

Edge cases to handle

Empty; only openers; only closers; deeply nested; mixed bracket types.

Complexity

O(strlen).

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.