pta题目:括号匹配

题目描述

给定仅包含“()[]{}”六种括号的字符串,请你判断该字符串中,括号的匹配是否是合法的,也就是对应括号的数量、嵌套顺序完全正确。

输入格式:
第一行一个整数T(T<=10)

其后T行每行一个字符串只包含[{()}]六种字符(字符串长度2e5以内)

输出格式:
对于每个字符串,匹配输出Yes,否则输出No

输入样例:

2
{
    
    ()[]}
([)]

输出样例:

Yes
No

分析

根据括号匹配的特点:每个右括号总是与离自己最近的左括号进行匹配,很适合使用栈(最近输入的符号,最先弹出)来对左括号进行存储,当遇到右括号需要与左括号进行匹配时,就可以将最近的左括号弹出来。

代码

#include <iostream>
#include <stack>

using namespace std;

int main() {
    
    
    int T;
    cin >> T;
    cin.ignore(); // 忽略换行符

    while (T-- > 0) {
    
    
        string line;
        getline(cin, line); // 读取整行输入
        stack<char> chStack; // 每组都是新的栈进行存储
        bool isValid = true;

        for (char ch : line) {
    
    
            if (ch == '(' || ch == '[' || ch == '{') {
    
    
                chStack.push(ch); // 左括号入栈
            } else {
    
    
                // 右括号时检查栈
                // 优先检查站是否为空
                if (chStack.empty()) {
    
    
                    isValid = false; // 栈空,表示没有对应的左括号
                    break;
                }
                char top = chStack.top();
                chStack.pop(); // 出栈

                // 检查匹配
                if ((ch == ')' && top != '(') || 
                    (ch == ']' && top != '[') || 
                    (ch == '}' && top != '{')) {
    
    
                    isValid = false;
                    break;
                }
            }
        }

        // 最后检查栈是否为空,若非空则有未匹配的左括号
        if (!chStack.empty()) {
    
    
            isValid = false;
        }

        // 输出结果
        cout << (isValid ? "Yes" : "No") << endl;
    }

    return 0;
}

关键逻辑

  • 只检查匹配性:通过 top 变量与对应右括号的比较来判断匹配是否正确,而不需要单独检查嵌套。
  • 使用栈的特性:由于栈是后进先出(LIFO)的结构,当我们遇到右括号时,它总是会与最近的左括号匹配,因此自然会保持正确的嵌套顺序。

嵌套顺序保证

在上述代码中,由于栈的结构,只有当每个右括号匹配其对应的左括号时,才会继续进行。如果出现不匹配,isValid 将会被设置为 false,并在最后检查栈是否为空,确保所有左括号都有匹配的右括号。

总结

通过使用栈来处理括号匹配,不仅可以验证匹配性,还可以确保嵌套顺序的正确性。只需专注于每个括号的匹配,嵌套顺序自然得以保证。

猜你喜欢

转载自blog.csdn.net/m0_74412436/article/details/143468811