题目描述
题目来源: acwing 3703 括号的匹配
在算术表达式中,除了加、减、乘、除等运算外,往往还有括号。
包括有大括号 {},中括号 [],小括号 (),尖括号 <> 等。
对于每一对括号,必须先左边括号,然后右边括号;
如果有多个括号,则每种类型的左括号和右括号的个数必须相等;
对于多重括号的情形,按运算规则,从外到内的括号嵌套顺序为:
大括号->中括号->小括号->尖括号,另外相同的括号可以嵌套。
例如,{[()]},{(())},{{}} 为一个合法的表达式,而 ([{}]),{([])},[{<>}] 都是非法的。
输入格式
第一行包含整数 n,表示共有 n个表达式需要判断。
接下来 n 行,每行包含一个括号表达式。
输出格式
每行输出一个表达式的判断结果。如果合法输出 YES,否则输出 NO。
数据范围
1≤n≤100
输入样例:
5
{[(<>)]}
[()]
<>()[]{}
[{}]
{()}
输出样例:
YES
YES
YES
NO
YES
解题思路与代码
#include <bits/stdc++.h>
using namespace std;
unordered_map<char, int> mp; // 建立一个map,用数字来指代各种括号更方便
// 单独建立一个函数,判断括号是否合法
bool check(string str) {
stack<int> sta; // 堆栈,用来装括号
for(auto c: str) { // 依次遍历字符串内的每一个元素
int t = mp[c]; // 将取出的括号转变为数字
if(t > 0) { // 进栈为右括号时
//若栈为空,或和栈顶元素不匹配,不合法
if(sta.empty() || sta.top() != -t) return false;
sta.pop(); // 匹配成功,出栈
} else { // 进栈为左括号时
//若栈中有元素,且新进元素优先级比栈顶元素优先级高,不合法
if(sta.size() && abs(t) > abs(sta.top())) return false;
sta.push(t); // 进栈
}
}
return sta.empty(); // 栈空说明所有括号匹配完成
}
int main() {
// 将一对括号存成相反数,按绝对值大小显示括号的优先级
mp['{'] = -4, mp['}'] = 4;
mp['['] = -3, mp[']'] = 3;
mp['('] = -2, mp[')'] = 2;
mp['<'] = -1, mp['>'] = 1;
int a;
cin >> a;
for (int i = 0; i < a; i ++) { // 一个字符串判断一次,共判断a次
string str;
cin >> str;
if(check(str))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}