题目描述
给定仅包含“()[]{}”六种括号的字符串,请你判断该字符串中,括号的匹配是否是合法的,也就是对应括号的数量、嵌套顺序完全正确。
输入格式:
第一行一个整数T(T<=10)
其后T行每行一个字符串只包含[{()}]六种字符(字符串长度2e5以内)
输出格式:
对于每个字符串,匹配输出Yes,否则输出No
输入样例:
2
{
()[]}
([)]
输出样例:
Yes
No
分析
根据括号匹配的特点:每个右括号总是与离自己最近的左括号进行匹配,很适合使用栈(最近输入的符号,最先弹出)来对左括号进行存储,当遇到右括号需要与左括号进行匹配时,就可以将最近的左括号弹出来。
代码
#include <iostream>
#include <stack>
using namespace std;
int main() {
int T;
cin >> T;
cin.ignore(); // 忽略换行符
while (T-- > 0) {
string line;
getline(cin, line); // 读取整行输入
stack<char> chStack; // 每组都是新的栈进行存储
bool isValid = true;
for (char ch : line) {
if (ch == '(' || ch == '[' || ch == '{') {
chStack.push(ch); // 左括号入栈
} else {
// 右括号时检查栈
// 优先检查站是否为空
if (chStack.empty()) {
isValid = false; // 栈空,表示没有对应的左括号
break;
}
char top = chStack.top();
chStack.pop(); // 出栈
// 检查匹配
if ((ch == ')' && top != '(') ||
(ch == ']' && top != '[') ||
(ch == '}' && top != '{')) {
isValid = false;
break;
}
}
}
// 最后检查栈是否为空,若非空则有未匹配的左括号
if (!chStack.empty()) {
isValid = false;
}
// 输出结果
cout << (isValid ? "Yes" : "No") << endl;
}
return 0;
}
关键逻辑
- 只检查匹配性:通过 top 变量与对应右括号的比较来判断匹配是否正确,而不需要单独检查嵌套。
- 使用栈的特性:由于栈是后进先出(LIFO)的结构,当我们遇到右括号时,它总是会与最近的左括号匹配,因此自然会保持正确的嵌套顺序。
嵌套顺序保证
在上述代码中,由于栈的结构,只有当每个右括号匹配其对应的左括号时,才会继续进行。如果出现不匹配,isValid 将会被设置为 false,并在最后检查栈是否为空,确保所有左括号都有匹配的右括号。
总结
通过使用栈来处理括号匹配,不仅可以验证匹配性,还可以确保嵌套顺序的正确性。只需专注于每个括号的匹配,嵌套顺序自然得以保证。