核心思路是:遇左括号压栈,遇右括号先检查栈非空且栈顶匹配对应左括号才弹出,否则非法;忽略非括号字符;用std::stack而非vector以保证语义安全和访问约束。

用 std::stack 判断括号是否成对出现
核心思路是:遇到左括号('(' 或 '[')就压栈,遇到右括号(')' 或 ']')就检查栈顶是否为对应左括号。不匹配或栈空时遇到右括号,直接判定非法。
关键点不是“能不能用栈”,而是「什么时候该弹出」「弹出前要不要检查类型」——漏掉任一条件都会导致误判。
- 必须严格配对:
')'只能匹配栈顶的'(',不能匹配'[' - 右括号来临时,若栈为空,说明没有可匹配的左括号 → 非法
- 遍历结束后栈非空,说明有左括号没被消耗 → 非法
常见错误:只检查栈非空,忽略括号类型匹配
典型 bug 是读到 ')' 时只判断 !stack.empty() 就 pop,却不校验栈顶是不是 '('。这样会让 "[)" 或 "()]" 这类串被误判为合法。
正确做法是:先检查栈是否为空,再取 stack.top() 对比,仅当类型匹配才 pop();否则直接返回 false。
立即学习“C++免费学习笔记(深入)”;
if (c == ')') {
if (stack.empty() || stack.top() != '(') return false;
stack.pop();
}
字符遍历中容易忽略的边界情况
输入不只有括号,还可能含字母、空格、数字等无关字符。这些必须跳过,否则 stack.top() 会访问到非法值(比如把字母当左括号压入)。
- 只对
'('、')'、'['、']'做处理,其余字符continue - 不要用
switch默认分支吞掉未知字符——万一漏写某个括号 case,逻辑就崩了 - 建议用
if-else if显式列出四个目标字符,其他一律忽略
为什么不用 std::vector 模拟栈?
虽然 vector 支持 push_back/pop_back,但语义不清晰,且易引发越界风险(比如误用 back() 前没检查 empty())。std::stack 强制封装,天然屏蔽随机访问,逼你写出更安全的配对逻辑。
另外,stack 底层默认用 deque,对小规模括号匹配(通常几十个以内)性能无感知差异,没必要手动换容器。
真正要留心的是:别在循环里反复调用 stack.size() 判断是否为空——它不是 O(1) 的(某些老标准库实现中 size() 是 O(n)),统一用 empty() 更稳妥。


















