题目
- 题目参考网址:https://vjudge.net/problem/UVA-673
- 大意:
实现匹配“[”,“]”和“(”,“)”,判断输入是否合法。
知识点
- 栈的应用
思路
设置一个栈,输入的括号序列从尾开始匹配,
- 若和栈顶括号匹配,则pop()出当前符号字符(第一个括号字符直接放入)。
- 若不匹配,则将当前位置的括号也压入栈。
直到括号序列遍历完毕,若栈中仍然有多的括号序列,则说明当前的括号序列不是合法输入序列。
代码
# include <iostream>
# include <cstdio>
# include <vector>
# include <stack>
using namespace std;
vector <string> ans;
bool is_paired(char a, char b) {
if (a == '[')
return b == ']';
if (a == '(')
return b == ')';
return false;
}
bool judge(string input) {
stack<char> vis;
// 从栈顶开始检查,消除
for (int i = input.length() - 1; i >= 0; i--){ // 从序列尾开始遍历
char temp = input[i]; // 当前括号序列位置的字符
if (!vis.empty()) {
// 栈顶先pop,如果匹配就不用压回去,不匹配则压回
char p = vis.top(); vis.pop();
if (!is_paired(temp, p)) { // 检查是否匹配,不匹配,则将当前位置的括号也压入栈
vis.push(p); // 先压如原先的栈顶
vis.push(temp);
}
} else{ // 第一个括号字符直接放入即可
vis.push(temp);
}
}
return vis.empty();
}
int main() {
int num; scanf("%d", &num); // 输入数量
for (int i = 0; i < num; i++) {
string input; cin >> input; // 符号序列
if(judge(input)){
ans.push_back("YES");
} else {
ans.push_back("NO");
}
}
for (string i:ans) // 输出结果
cout << i << endl;
}
过程中遇到的问题 & 解决
- 没有什么问题… 只要注意是从字符序列尾开始反向遍历匹配即可。
测试
输入:
3
([])
(([()])))
([()[]()])()
#
结果:
YES
NO
YES