题解——括号匹配
题目链接:传送门
描述
假设表达式中只包含三种括号:圆括号、方括号和花括号,它们可相互嵌套,如([{}])
或({[][()]})
等均为正确的格式,而{[]})}
或{[()]
或([]}
均为不正确的格式.
输入一串括号
如果输入的右括号多余,输出:Extra right brackets
如果输入的左括号多余, 输出:Extra left brackets
如果输入的括号不匹配,输出:Brackets not match
如果输入的括号匹配,输出:Brackets match
输入
{{{{)))
输出
Brackets not match
样例输入
{([)]}
样例输出
Brackets not match
提示
利用栈结构
题解
因为栈的结构恰好是先进后出,所以我们用字符串读取所有括号后,从左到右扫描一遍,如果:
- 扫描到左括号
(
或[
或{
,将它入栈,继续扫描; - 扫描到右括号
)
或]
或}
,判断当前栈顶元素是不是与之匹配的左括号,如果:- 这时候栈顶没有元素了,那么说明右括号多了,输出
Extra right brackets
,扫描结束; - 恰好匹配,则将左括号出栈并继续扫描;
- 不匹配,输出
Brackets not match
,扫描结束;
- 这时候栈顶没有元素了,那么说明右括号多了,输出
按上面的方式扫描,如果中间没有因为特殊原因终止,而是顺利扫描完了整个字符串,那么:
- 如果此时栈内还有元素,注意上面的操作中只有左括号入栈,没有右括号入栈,所以说明左括号多了,输出
Extra left brackets
- 如果此时栈空了,说明正好匹配完,输出
Brackets match
#include <iostream>
#include <cstring>
#include <stack> //方便起见,直接用stl里的栈啦
using namespace std;
stack<char> st;
char s[1000];
int main()
{
cin>>s;
bool f=1; //用于标记“因为特殊原因结束扫描”
for(int i=0;i<strlen(s);i++){
if(s[i]=='('||s[i]=='['||s[i]=='{')
st.push(s[i]);
if(s[i]==')'||s[i]==']'||s[i]=='}'){
if(st.empty()){
cout<<"Extra right brackets"<<endl;
f=0; //因为特殊原因结束扫描
break;
}
else{
int sum=(int)s[i]+(int)st.top(); //用ascii码检验括号是否匹配
if(sum==123+125||sum==91+93||sum==40+41)
{
st.pop();
continue;
}
else{
cout<<"Brackets not match"<<endl;
f=0; //因为特殊原因结束扫描
break;
}
}
}
}
if(f)
{
if(st.empty())
cout<<"Brackets match"<<endl;
else
cout<<"Extra left brackets"<<endl;
}
return 0;
}