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

Check that all brackets in a string are correctly matched and nested.

Task

Implement int balanced_brackets(const char *s) that returns 1 if the brackets in s are correctly matched and nested, else 0. Recognised pairs are (), [], and {}; all other characters are ignored.

Input

s: a NUL-terminated string that may contain brackets and any other characters.

Output

int: 1 if balanced, 0 otherwise.

Example

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

Edge cases

  • Empty string is balanced (returns 1).
  • A closer with no matching opener fails immediately.
  • An opener never closed fails at end of string.

Rules

  • Use an array as a stack; assume a maximum nesting depth of 512.

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

s: a NUL-terminated string; non-bracket characters are ignored.

Output format

int: 1 if brackets are balanced, else 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.