题解——括号匹配

题目链接:传送门

描述

假设表达式中只包含三种括号:圆括号、方括号和花括号,它们可相互嵌套,如([{}])({[][()]})等均为正确的格式,而{[]})}{[()]([]}均为不正确的格式.

输入一串括号
如果输入的右括号多余,输出: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;
}