洛谷题单指南-线性表-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;
}