原题目链接:
P1241 括号序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
原题目截图:
思路分析:
如果读懂了题意,这道题其实不难。
重点是理解这句话:
对于当前的字符,如果它是一个右括号,考察它与它左侧离它最近的未匹配的的左括号。如果该括号与之对应(即小括号匹配小括号,中括号匹配中括号),则将二者配对。如果左侧未匹配的左括号不存在或与之不对应,则其配对失败。
配对结束后,对于 s 中全部未配对的括号,请你在其旁边添加一个字符,使得该括号和新加的括号匹配。
总结的说就是:先遍历每个括号,标记它是不是匹配的。然后遍历结束后,把“不匹配的括号”改写成成对的括号输出,“匹配的括号”则不变。
栈+字符串
图示过程:
解决代码:
#include<iostream> // 包含标准输入输出流库
using namespace std; // 使用标准命名空间
#include<stack> // 包含栈库
#include<vector> // 包含向量库
#include<utility> // 包含用于定义pair的库
int main() {
string s; // 定义一个字符串s
cin >> s; // 从标准输入读取字符串
stack<pair<char,int>> sta; // 定义一个栈,存储字符及其索引的pair
vector<int>match(s.size(),0); // 定义一个向量,用于标记括号是否匹配,初始化为0
for (int i = 0; i < s.size(); i++) { // 遍历字符串
if (s[i] == ']') { // 如果当前字符是']'
if (!sta.empty() && sta.top().first == '[') { // 如果栈不为空且栈顶字符是'['
match[sta.top().second] = 1; // 标记栈顶字符对应的括号为匹配
match[i] = 1; // 标记当前字符对应的括号为匹配
sta.pop(); // 弹出栈顶元素
}
}
else if (s[i] == ')') { // 如果当前字符是')'
if (!sta.empty() && sta.top().first == '(') { // 如果栈不为空且栈顶字符是'('
match[sta.top().second] = 1; // 标记栈顶字符对应的括号为匹配
match[i] = 1; // 标记当前字符对应的括号为匹配
sta.pop(); // 弹出栈顶元素
}
}
else sta.push({s[i],i}); // 如果当前字符不是']'或')',则压入栈中
}
for (int i = 0; i < s.size(); i++) { // 再次遍历字符串
if (match[i] == 0) { // 如果当前字符对应的括号没有匹配
switch (s[i]) { // 根据当前字符类型输出未匹配的括号
case '(':cout << "()"; break;
case '[':cout << "[]"; break;
case ']':cout << "[]"; break;
case ')':cout << "()"; break;
}
}
else cout << s[i]; // 如果当前字符对应的括号已经匹配,则直接输出
}
return 0; // 程序结束
}
今天的博客写到这里,诸君共勉之!