[프로그래머스 C++] 괄호 변환

 

https://school.programmers.co.kr/learn/courses/30/lessons/60058

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


 

 

해결전략

 

재귀 함수 Recursion

문자열

 


 

정답 코드

 

#include <iostream>
#include <string>
using namespace std;
bool isCorrect(string str) // '올바른 괄호 문자열'인지 검사하는 함수
{
int cnt = 0;
for (char ch : str)
{
if (ch == '(')
cnt++;
else
cnt--;
if (cnt < 0) return false; // cnt가 0보다 작아지면 올바르지 않은 괄호 문자열
}
return cnt == 0; // 문자열의 끝까지 검사했을 때 cnt가 0이면 올바른 괄호 문자열
}
string Reverse(string str) // 괄호의 방향을 뒤집는 함수
{
string result = "";
for (char c : str)
{
if (c == '(')
result += ")"; // '(' 이면 ')'로 변경
else
result += "("; // ')' 이면 '('로 변경
}
return result; // 뒤집은 문자열 반환
}
string solve(string p) // 주어진 괄호 문자열을 올바른 괄호 문자열로 변환하는 함수
{
if (p == "") // 예외처리: 빈 문자열이면 그대로 반환
return p;
string u = "", v = "";
int cnt = 0;
for (int i = 0; i < p.size(); ++i)
{
if (p[i] == '(')
cnt++;
else
cnt--;
if (cnt == 0) // cnt가 0이 되는 지점에서 u, v 분리
{
u = p.substr(0, i + 1);
v = p.substr(i + 1);
break;
}
}
if (isCorrect(u)) // u가 올바른 괄호 문자열이면
return u + solve(v); // u와 변환된 v를 붙여서 반환
else // u가 올바르지 않은 괄호 문자열이면
return "(" + solve(v) + ")" + Reverse(u.substr(1, u.size() - 2)); // '(' + 변환된 v + ')' + 뒤집은 u의 가운데 부분을 반환
}
string solution(string p) {
return solve(p);
}
int main()
{
cout << solution("(()())()") << "\n";
cout << solution(")(") << "\n";
cout << solution("()))((()") << "\n";
return 0;
}

 

 


 

방법론

 

 

// 방법 1
string result = "";
for (char c : str)
{
if (c == '(')
result += ")"; // '(' 이면 ')'로 변경
else
result += "("; // ')' 이면 '('로 변경
}
// 방법 2
string result = "";
for (char &c : str)
{
c = c == '(' ? ')' : '(';
result += c;
}

 


 

 

 

디버깅 화면 확인하기

 

#include <iostream>
#include <string>
using namespace std;
bool isCorrect(string str) // '올바른 괄호 문자열'인지 검사하는 함수
{
int cnt = 0;
for (char ch : str)
{
if (ch == '(')
cnt++;
else
cnt--;
if (cnt < 0) return false; // cnt가 0보다 작아지면 올바르지 않은 괄호 문자열
}
return cnt == 0; // 문자열의 끝까지 검사했을 때 cnt가 0이면 올바른 괄호 문자열
}
string Reverse(string str) // 괄호의 방향을 뒤집는 함수
{
string result = "";
for (char c : str)
{
if (c == '(')
result += ")"; // '(' 이면 ')'로 변경
else
result += "("; // ')' 이면 '('로 변경
}
return result; // 뒤집은 문자열 반환
}
string solve(string p) // 주어진 괄호 문자열을 올바른 괄호 문자열로 변환하는 함수
{
if (p == "") // 예외처리: 빈 문자열이면 그대로 반환
return p;
string u = "", v = "";
int cnt = 0;
for (int i = 0; i < p.size(); ++i)
{
if (p[i] == '(')
cnt++;
else
cnt--;
if (cnt == 0) // cnt가 0이 되는 지점에서 u, v 분리
{
u = p.substr(0, i + 1);
v = p.substr(i + 1);
break;
}
}
cout << "u = " << u << " v = " << v << "\n";
if (isCorrect(u)) // u가 올바른 괄호 문자열이면
return u + solve(v); // u와 변환된 v를 붙여서 반환
else // u가 올바르지 않은 괄호 문자열이면
return "(" + solve(v) + ")" + Reverse(u.substr(1, u.size() - 2)); // '(' + 변환된 v + ')' + 뒤집은 u의 가운데 부분을 반환
}
string solution(string p) {
return solve(p);
}
int main()
{
cout << solution("(()())()") << "\n\n";
cout << solution(")(") << "\n\n";
cout << solution("()))((()") << "\n\n";
return 0;
}