题目:
字符串中只含有括号 <>,(),[],{},判断输入的字符串中括号是否匹配。如果括号有互相包含的形式,从内到外必须是<>,(),[],{},例如输入为[()],输出YES,输入([]),或者><则输出为NO;
分析:
大体思路:创建一个栈,每碰到一个左括号,就压入栈中,碰到右括号就弹出一个相应的左括号。将左括号压入栈中时,要比较括号的优先顺序。
具体思路:
(1)准备:创建一个栈,和一个数组(用数字来标记括号的优先级),还有两个左括号和右括号的字符组,左括号的等级为正值,右括号为负值,开头用空字符,把0号位给占了,调整好顺序。
stack<char> opchar;
char c1[5] = { ' ','<','(','[','{' };//1 2 3 4
char c2[5] = { ' ','>',')',']','}' };//-1 -2 -3 -4
(2)判断过程
在主函数中设立好参数。flag用来标识字符串是否符合规则
int rank[100], len = 0;
int n;
cin >> n;
char m[255];
bool flag = true;
接下来的判断过程,我利用注释来进行解释,其中一些注释的代码是我在调试过程中使用到的,有需要的可以参考一下。
for (int j = 0; j < n; j++) {
cin >> m;
int s = 0; //用于标识这是字符串中第几个字符
len = 0; //每判读完一次,就要归零
/*************************************************/
//获取一个符号的等级
for (int i = 1; i <= 4; i++)
{
//cout << c1[i] << endl;
if (m[s] == c1[i])
{
rank[0] = i;
opchar.push(m[s]);
break;
}
}
//如果顺序不对,即字符串一开始右括号,那么栈必定是空的
//输出NO,并标记flag
if (opchar.empty())
{
flag = false;
cout << "NO" << endl;
break;
}
s++; len++;//移动到下一个字符,栈的元素个数加一
//如果开头顺序,对了就继续
while (s!=strlen(m))//
{
//获取下一个符号的等级
int new_rank;
for (int i = 1; i <= 4; i++) {
if (m[s] == c1[i])
{
//cout << c1[i] << endl;
new_rank = i;
break;
}
if (m[s] == c2[i])
{
//cout << c2[i] << endl;
new_rank = -i;
break;
}
}
//对新符号处理
//收到一个左括号
if (new_rank > 0)
{
//cout << '1' << endl;
//优先级顺序正确 或者 栈中没有元素
if (len == 0 || rank[len - 1] >= new_rank) {
//cout << "1.1" << endl;
opchar.push(m[s]);
rank[len++] = new_rank;
}
//优先级顺序不正确
else {
//cout << "1.2" << endl;
flag = false;
cout << "NO" << endl;
break;
}
}
//收到一个右括号
else {
//cout << '2' << endl;
//栈中没有左括号
if (opchar.empty()) {
//cout << "2.1" << endl;
flag = false;
cout << "NO" << endl;
break;
}
//栈中有左括号
else {
//cout << "2.2" << endl;
//右符号的对应的左括号是栈顶元素能进行配对
if (c1[-new_rank] == opchar.top())
{
//cout << "2.2.1" << endl;
opchar.pop();
len--;
}
//右符号的对应的左括号不是栈顶元素,不能进行配对
else {
//cout << "2.2.2" << endl;
flag = false;
cout << "NO" << endl;
break;
}
}
}
s++;//移动到下一个字符
}
//对一个字符串判断结束后,栈为空,并且flag表示为true,输出YES,否则输出NO
if (opchar.empty() && flag)cout << "YES" << endl;
else cout << "NO" << endl;
}
最后将完整代码吗放在后面,可能会存在不对的地方,还请指正
#include<iostream>
#include<stack>
#include<string>
using namespace std;
stack<char> opchar;
char c1[5] = { ' ','<','(','[','{' };//1 2 3 4
char c2[5] = { ' ','>',')',']','}' };//-1 -2 -3 -4
bool flag = true;
int main()
{
int rank[100], len = 0;
int n;
cin >> n;
char m[255];
for (int j = 0; j < n; j++) {
cin >> m;
int s = 0;
len = 0;
//获取一个符号的等级
for (int i = 1; i <= 4; i++)
{
//cout << c1[i] << endl;
if (m[s] == c1[i])
{
rank[0] = i;
opchar.push(m[s]);
break;
}
}
//如果顺序不对
if (opchar.empty())
{
flag = false;
cout << "NO" << endl;
break;
}
s++; len++;
//如果顺序对了就继续
while (s!=strlen(m))
{
//获取等级
int new_rank;
for (int i = 1; i <= 4; i++) {
if (m[s] == c1[i])
{
//cout << c1[i] << endl;
new_rank = i;
break;
}
if (m[s] == c2[i])
{
//cout << c2[i] << endl;
new_rank = -i;
break;
}
}
//对新符号处理
if (new_rank > 0)
{
//cout << '1' << endl;
if (len == 0 || rank[len - 1] >= new_rank) {
//cout << "1.1" << endl;
opchar.push(m[s]);
rank[len++] = new_rank;
}
else {
//cout << "1.2" << endl;
flag = false;
cout << "NO" << endl;
break;
}
}
else {
//cout << '2' << endl;
if (opchar.empty()) {
//cout << "2.1" << endl;
flag = false;
cout << "NO" << endl;
break;
}
else {
if (c1[-new_rank] == opchar.top())
{
//cout << "2.2.1" << endl;
opchar.pop();
len--;
}
else {
//cout << "2.2.2" << endl;
flag = false;
cout << "NO" << endl;
break;
}
}
}
s++;
}
if (opchar.empty() && flag)cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}