Bootstrap

洛谷 P1241 括号序列

P1241 括号序列

题目描述

定义如下规则:

  1. 空串是「平衡括号序列」
  2. 若字符串 S S S 是「平衡括号序列」,那么 [ S ] \texttt{[}S\texttt] [S] ( S ) \texttt{(}S\texttt) (S) 也都是「平衡括号序列」
  3. 若字符串 A A A B B B 都是「平衡括号序列」,那么 A B AB AB(两字符串拼接起来)也是「平衡括号序列」。

例如,下面的字符串都是平衡括号序列:

  • ()[](())([])()[]()[()]

而以下几个则不是:

  • ([])(())([()

现在,给定一个仅由 ()[]构成的字符串 s s s,请你按照如下的方式给字符串中每个字符配对:

  1. 从左到右扫描整个字符串。
  2. 对于当前的字符,如果它是一个右括号,考察它与它左侧离它最近未匹配的的左括号。如果该括号与之对应(即小括号匹配小括号,中括号匹配中括号),则将二者配对。如果左侧未匹配的左括号不存在或与之不对应,则其配对失败。

配对结束后,对于 s s s 中全部未配对的括号,请你在其旁边添加一个字符,使得该括号和新加的括号匹配。

输入格式

输入只有一行一个字符串,表示 s s s

输出格式

输出一行一个字符串表示你的答案。

输入输出样例 #1

输入 #1

([()

输出 #1

()[]()

输入输出样例 #2

输入 #2

([)

输出 #2

()[]()

说明/提示

数据规模与约定

对于全部的测试点,保证 s s s 的长度不超过 100 100 100,且只含 ()[] 四种字符。

题目分析

这道题与力扣上的有效的括号十分类似,但是我被这道题卡了很久,主要问题还是理解题意。

一开始理解的是将所有的括号都匹配,但是实际上是将所有的右括号与左侧最近的未匹配的左括号匹配。

第一版错误答案:

#include <iostream>
#include <stack>
using namespace std;

stack<int> st;
stack<char> ch; 

int main(){
	string s;
	cin >> s;
	for(int i = 0; i < s.size(); i++){
		if(s[i] == '('||s[i] == '[') st.push(i);
		else if(s[i] == ')'){
			if(st.empty()){
				st.push(i);
				continue;
			}
			if(s[st.top()] == '('&&st.size()) {
				st.pop();
			}
			else st.push(i);
		}
		else if(s[i] == ']'){
			if(st.empty()){
				st.push(i);
				continue;
			}
			if(s[st.top()] == '['&&st.size()) {
				st.pop();
			}
			else st.push(i);
		}
	}
		for(int i = s.size() - 1;i >= 0;i--){
			if(st.size()&&i == st.top()){
				if(s[i] == '('||s[i] == ')'){
					ch.push(')');
					ch.push('(');
					st.pop();
				}
				else if(s[i] == '['||s[i] == ']'){
					ch.push(']');
					ch.push('[');
					st.pop();
				}
			}
			else ch.push(s[i]);
		}
	while(ch.size()){
		cout << ch.top() ;
		ch.pop();
	}
	return 0;
}

得分:68分

错误用例(在题解里的一个作者提到的):([)]) 正确输出:([()]) 实际输出:()[]()[]()

这里的问题在于,右括号与左侧最近的未匹配的左括号匹配,而不是与左侧最近的左括号匹配。

正确答案:

#include <iostream>
#include <stack>
using namespace std;

stack<int> st,don;
stack<char> ch; 

int main(){
	string s;
	cin >> s;
	for(int i = 0; i < s.size(); i++){
		if(s[i] == '('||s[i] == '[') st.push(i);
		else if(s[i] == ')'){
			if(st.empty()) continue;
			if(s[st.top()] == '('&&st.size()) {
				st.pop();
                don.push(i);
			}
		}
		else if(s[i] == ']'){
			if(st.empty()) continue;
			if(s[st.top()] == '['&&st.size()) {
				st.pop();
                don.push(i);
			}
		}
	}
    for(int i = s.size()-1;i >= 0;i--){
        if(s[i] == '('){
            if(!st.empty() && i == st.top()){
                ch.push(')');
                ch.push('(');
                st.pop();
            }
            else{
                ch.push(s[i]);
            }
        }
        else if(s[i] == ')'){
            if(!don.empty() && i == don.top()){
                ch.push(s[i]);
                don.pop();
            }
            else{
                ch.push(')');
                ch.push('(');
            }
        }
        else if(s[i] == '['){
            if(!st.empty() && i == st.top()){
                ch.push(']');
                ch.push('[');
                st.pop();
            }
            else{
                ch.push(s[i]);
            }
        }
        else if(s[i] == ']'){
            if(!don.empty() && i == don.top()){
                ch.push(s[i]);
                don.pop();
            }
            else{
                ch.push(']');
                ch.push('[');
            }
        }
    }
    while(ch.size()){
        cout << ch.top();
        ch.pop();
    }
	return 0;
}
;