【问题描述】
一个合法的括号串,是指只包含括号的串,如果满足如下条件:
(1)<> () [] {} 这四对括号是合法的;
(2)如果r是合法括号串,则<r> (r) [r] {r}也是;
(3)如果r,s是合法括号串,则rs也是;
所以<<>> , [<>{}(())],[({<>})]是合法的括号串,而)(,[( ])就不是。
【输入形式】
输入第一行正整数t (10 ≤ n ≤ 100),表示有多少组测试数据。
后面有t行,每行一个只包含8种括号符号的括号串。
40%的括号串的长度L 2 ≤ L≤ 20;
30%的括号串的长度L 2 ≤ L≤ 200;
20%的括号串的长度L 2 ≤ L≤ 2000;
10%的括号串的长度L 2 ≤ L≤ 20000;
【输出形式】
对于每组测试数据,如果括号串是合法的,输出“Yes”(输出没有引号)占一行,否则,输出“No”(输出没有引号)占一行。
【样例输入】
6 <<>> )( [<>{}(())] [({<>})] [(]) <([{
【样例输出】
Yes No Yes Yes No No
算法思想:
-
对于每个输入的字符串,我们使用一个栈来检查括号的匹配情况。
-
遍历输入字符串的每个字符:
- 如果遇到左括号(
<
、(
、[
、{
),将其压入栈中。 - 如果遇到右括号(
>
、)
、]
、}
),需要进行匹配检查:- 如果栈为空,表示当前右括号没有与之匹配的左括号,将当前右括号压入栈中,并且结束检查。
- 否则,取出栈顶元素,与当前右括号进行匹配检查:
- 如果匹配成功,则将栈顶元素弹出。
- 如果匹配失败,则将当前右括号压入栈中,并且结束检查。
- 如果遇到左括号(
-
检查结束后,判断栈是否为空:
- 如果栈为空,表示所有左括号都有与之匹配的右括号,输出 "Yes"。
- 如果栈不为空,表示有未匹配的左括号或多余的右括号,输出 "No"。
#include <iostream>
#include <stack>
#include <cstring>
int main() {
int n;
std::cin >> n;
for (int i = 0; i < n; i++) {
std::stack<char> a; // 创建栈a,用于括号匹配
std::string test;
std::cin >> test;
for (int j = 0; j < test.length(); j++) {
if (test[j] == '<' || test[j] == '(' || test[j] == '[' || test[j] == '{') {
a.push(test[j]); // 遇到左括号,将其压入栈中
}
if (test[j] == '>' || test[j] == ')' || test[j] == ']' || test[j] == '}') {
if (a.empty()) {
a.push(test[j]); // 栈为空,当前右括号没有与之匹配的左括号,将其压入栈中并结束检查
break;
}
char b = a.top(); // 取出栈顶元素
if ((b == '<' && test[j] == '>') || (b == '(' && test[j] == ')') || (b == '[' && test[j] == ']') || (b == '{' && test[j] == '}')) {
a.pop(); // 匹配成功,弹出栈顶元素
} else {
a.push(test[j]); // 匹配失败,将当前右括号压入栈中并结束检查
break;
}
}
}
if (a.empty()) {
std::cout << "Yes" << std::endl; // 栈为空,所有括号匹配成功
} else {
std::cout << "No" << std::endl; // 栈不为空,括号匹配失败
}
}
return 0;
}