std::stack是最稳妥选择,但必须处理空栈弹出、类型错配、遍历后栈非空三类边界;单靠字符相等无法判断括号匹配,需结合栈顶检查层级与类型,且遍历结束后必须验证栈为空。

直接结论:用 std::stack 是最稳妥的选择,但必须处理三类边界——空栈弹出、类型错配、遍历后栈非空;漏掉任一都会导致误判。
为什么不能只靠 if (c == ')') 判断右括号?
单靠字符相等无法区分嵌套层级和交叉错误。比如 "([)]" 中,')' 确实出现了,但它前面最近的左括号是 '[',而非 '(',必须检查栈顶才能发现不匹配。
- 只比字符不查栈顶 → 会把
"([)]"当作合法 - 遇到右括号时没先判
stk.empty()→ 程序崩溃(top()或pop()对空栈调用是未定义行为) - 忽略
'{'和'}'的支持 → 遇到 JSON 或 C++ 源码片段直接失效
std::stack<char></char> 的入栈/出栈时机怎么卡准?
入栈只发生在明确的左括号上;出栈仅在右括号触发且栈顶匹配时发生——不是“看到右括号就 pop”,而是“看到右括号 → 查栈顶 → 类型对得上才 pop”。
- 入栈条件:
c == '(' || c == '[' || c == '{' - 出栈条件:栈非空 且
(c == ')' && stk.top() == '(')或同理处理[]和{} - 一旦发现右括号但栈顶不匹配(如
')'对应'['),立刻返回false,不要继续
为什么遍历完必须检查 stk.empty()?
字符串结尾可能残留未闭合的左括号,例如 "(([" 或 "{[()" —— 这些不会在遍历时触发错误,但显然非法。
- 漏掉这步,
"a(b[c{"会被判为合法 - 常见写法是
return stk.empty();作为函数最终返回值 - 如果还要定位错误位置(比如报第 5 个字符不匹配),就得额外维护索引变量,不能只依赖栈内字符
真正容易被忽略的是:栈里存的是字符还是下标,取决于你要返回「是否合法」还是「哪里不合法」。前者存 char 足够,后者必须存位置索引并配合原字符串做映射——这个选择点,很多人一开始就没想清楚。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











