括号序列
题目描述
定义如下规则:
- 空串是「平衡括号序列」
- 若字符串 S 是「平衡括号序列」,那么 [S] 和 (S) 也都是「平衡括号序列」
- 若字符串 A 和 B 都是「平衡括号序列」,那么 AB(两字符串拼接起来)也是「平衡括号序列」。
例如,下面的字符串都是平衡括号序列:
()
,[]
,(())
,([])
,()[]
,()[()]
而以下几个则不是:
(
,[
,]
,)(
,())
,([()
现在,给定一个仅由 (
,)
,[
,]
构成的字符串 s,请你按照如下的方式给字符串中每个字符配对:
1. 从左到右扫描整个字符串。
2. 对于当前的字符,如果它是一个右括号,考察它与它左侧离它最近的未匹配的的左括号。如果该括号与之对应(即小括号匹配小括号,中括号匹配中括号),则将二者配对。如果左侧未匹配的左括号不存在或与之不对应,则其配对失败。
配对结束后,对于 s 中全部未配对的括号,请你在其旁边添加一个字符,使得该括号和新加的括号匹配。
输入格式
输入只有一行一个字符串,表示 s。
输出格式
输出一行一个字符串表示你的答案。
样例 #1
样例输入 #1
([()
样例输出 #1
()[]()
样例 #2
样例输入 #2
([)
样例输出 #2
()[]()
提示
数据规模与约定
对于全部的测试点,保证 s 的长度不超过 100,且只含 (
,)
,[
,]
四种字符。
算法1
(栈) O(n2)
关键点:它是一个右括号,考察它与它左侧离它最近的未匹配的的左括号
1.用栈维护所有在左括号
2.当遇到右括号,则取出栈顶元素,看是否能匹配
3.如果能匹配那么弹出栈顶,并且标记为已匹配
4.最后遍历所有字符,标记为已匹配的直接输出,未标记的输出对应的括号
注意点: 当栈顶空的时候不能取出栈顶,因此先特判栈是否为空
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
string s;
bool mark[N];
struct node{
char c;
int idx;
};
int main(){
cin>>s;
stack <node> stk;
for(unsigned int i=0;i<s.size();i++){
if(s[i] == '(' || s[i] =='['){
stk.push({s[i],(int)i});
continue;
}
if(stk.empty()) continue; //当栈空的时候不能取出栈顶
auto t = stk.top();
if(s[i]==')'&&t.c=='(' || s[i]==']'&&t.c=='['){
mark[t.idx] = 1;
mark[i] = 1;
stk.pop();
}
}
for(unsigned int i=0;i<s.size();i++){
if(mark[i]) cout<<s[i];
else{
if(s[i]==')'||s[i]=='(')
cout<<"()";
else cout<<"[]";
}
}
return 0;
}