洛谷题单指南-线性表-P1241 括号序列

原题链接:https://www.luogu.com.cn/problem/P1241

题意解读:括号配对问题,直观上是堆栈的应用。关键的匹配策略是读懂该句:考察它与它左侧离它最近未匹配的的左括号。

解题思路:

本题所需核心数据结构是堆栈,由于要实现从栈顶找到第一个未匹配的左括号,所以堆栈中只存所有左括号。

从左到右遍历字符串,如果是左括号,直接入栈,

如果是右括号,判断栈顶左括号是否与其配对,如果配对则用flag数组标记已配对过的左括号、右括号的位置,且栈顶左括号出栈,因为已经配对过,

最后遍历原始字符串,如果标记是未配对字符,输出时给与配对,否则直接输出。

100分代码:

#include <bits/stdc++.h>
using namespace std;

struct node 
{
    char c;
    int idx;
};

string s;
stack<node> stk; //堆栈存未配对的左括号
int top = 0; //栈顶位置
bool flag[105]; //括号是否已配对

int main()
{
    cin >> s;
    for(int i = 0; i < s.size(); i++)
    {
        if(s[i] == ')' || s[i] == ']') //如果是右括号
        {
            if(stk.empty()) continue; //没有找到未配对的左括号
            node n = stk.top(); //第一个未配对的左括号
            if(n.c == '(' && s[i] == ')' || n.c == '[' && s[i] == ']') 
            {
                flag[n.idx] = true; //将左括号位置标记为已配对
                flag[i] = true; //将右括号位置标记为已配对
                stk.pop(); //已配对的左括号出栈
            }
        }
        else stk.push({s[i], i}); //左括号直接入栈
    }

    for(int i = 0; i < s.size(); i++)
    {
        if(!flag[i]) //如果未配对过,输出配对的结果
        {
            if(s[i] == '(' || s[i] == ')') cout << "()";
            else if(s[i] == '[' || s[i] == ']') cout << "[]";
        }
        else cout << s[i]; //已配对过的直接输出
    }

    return 0;
}

 

posted @ 2024-03-12 11:53  五月江城  阅读(64)  评论(0编辑  收藏  举报