Problem1841:有效的括号
题目描述
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
输入
多组数据
每组是一个由'(',')','{','}','[',']' 组成的括号序列
每组字符串长度不超过50。
输出
如果有效输出true, 否则输出false。
样例输入
() ()[]{} (] ([)] {[]}
样例输出
true true false false true
解决
看起来题目是蛮简单的根据题意只需要判断是不是括号都是闭合的就就解决了。
但是实际上问题就在于要求的第二行。必须以正确的顺序闭合。小括号内不能有中括号和大括号,中括号内不能有大括号。需要满足这个顺序要求。
原本打算找个变量计数每种括号的个数,就排除了个数上不匹配的情况。
给每个情况做限定比如‘(’后面必须是‘)’,‘[’后面可以有‘]’和‘(’........
这种无脑判断指定太复杂写到一半就乱了(╯°Д°)╯︵ ┻━┻。
后来发现数据结构中的栈可以将过程简化并且让思路简单┬─┬ ノ('-'ノ) (摆好摆好)。
简单来讲就是让 ' ( ' , ' [ ' , ' { '统统进栈,遇到他们的反括号后让其出栈,最后判断栈空,若空则出栈。
在判断字符串是否为 ' ( ' , ' [ ' , ' { '并入栈操作后,应当判断栈是否为空,这样可以排除首个字符就是反括号的情况,同时也可以排除反括号比正括号多的情况。
之后判断栈顶元素是否与目前遇到的反括号匹配,若匹配,则出栈。
贴OJ上AC源码
#include <iostream>
#include<stack>
using namespace std;
stack<char> a;
string buff;
bool tag = true; //立旗子为后续判断做准备
int main() {
while(cin >> buff) {
tag = true;
for(int i = 0; i < buff.size(); i++) {
if(buff[i] == '(' || buff[i] == '[' || buff[i] == '{') {
a.push(buff[i]); //先判断括号让正向括号入栈
} else if(a.empty()) { //判断栈空若空则说明括号个数或顺序不匹配,拔了旗子直接跳出
tag = false;
break;
} else {
if(buff[i] == ')' && a.top() == '(') { //判断栈顶的正向括号与反括号是否匹配
a.pop();
} else if (buff[i] == ']' && a.top() == '[') {
a.pop();
} else if (buff[i] == '}' && a.top() == '{') {
a.pop();
} else {
tag = false;
break;
}
}
}
if(tag == false || !a.empty()) //栈不空或者被拔了旗子则表示false
cout << "false" << endl;
else
cout << "true" << endl;
while(!a.empty()) {
a.pop(); //初始化全局变量
}
}
return 0;
}
/**************************************************************
Problem: 1841
User: 08173084
Language: C++
Result: 正确
Time:0 ms
Memory:1704 kb
****************************************************************/
总结
数据结构和模板库能简化问题!!