Skip to content

Commit 8966cc0

Browse files
committed
[level 2] Title: 괄호 변환, Time: 20.84 ms, Memory: 92.6 MB -BaekjoonHub
1 parent af36a48 commit 8966cc0

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# [level 2] 괄호 변환 - 60058
2+
3+
[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/60058)
4+
5+
### 성능 요약
6+
7+
메모리: 92.6 MB, 시간: 20.84 ms
8+
9+
### 구분
10+
11+
코딩테스트 연습 > 2020 KAKAO BLIND RECRUITMENT
12+
13+
### 채점결과
14+
15+
정확성: 100.0<br/>합계: 100.0 / 100.0
16+
17+
### 제출 일자
18+
19+
2025년 08월 28일 11:25:52
20+
21+
### 문제 설명
22+
23+
<p>카카오에 신입 개발자로 입사한 <strong>"콘"</strong>은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를 컴파일하여 로그를 보니 대부분 소스 코드 내 작성된 괄호가 개수는 맞지만 짝이 맞지 않은 형태로 작성되어 오류가 나는 것을 알게 되었습니다.<br>
24+
수정해야 할 소스 파일이 너무 많아서 고민하던 "콘"은 소스 코드에 작성된 모든 괄호를 뽑아서 올바른 순서대로 배치된 괄호 문자열을 알려주는 프로그램을 다음과 같이 개발하려고 합니다.</p>
25+
26+
<h3>용어의 정의</h3>
27+
28+
<p><strong>'('</strong> 와 <strong>')'</strong> 로만 이루어진 문자열이 있을 경우, '(' 의 개수와 ')' 의 개수가 같다면 이를 <strong><code>균형잡힌 괄호 문자열</code></strong>이라고 부릅니다.<br>
29+
그리고 여기에 '('와 ')'의 괄호의 짝도 모두 맞을 경우에는 이를 <strong><code>올바른 괄호 문자열</code></strong>이라고 부릅니다.<br>
30+
예를 들어, <code>"(()))("</code>와 같은 문자열은 "균형잡힌 괄호 문자열" 이지만 "올바른 괄호 문자열"은 아닙니다.<br>
31+
반면에 <code>"(())()"</code>와 같은 문자열은 "균형잡힌 괄호 문자열" 이면서 동시에 "올바른 괄호 문자열" 입니다.</p>
32+
33+
<p>'(' 와 ')' 로만 이루어진 문자열 w가 "균형잡힌 괄호 문자열" 이라면 다음과 같은 과정을 통해 "올바른 괄호 문자열"로 변환할 수 있습니다.</p>
34+
<div class="highlight"><pre class="codehilite"><code>1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다.
35+
2. 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리합니다. 단, u는 "균형잡힌 괄호 문자열"로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다.
36+
3. 문자열 u가 "올바른 괄호 문자열" 이라면 문자열 v에 대해 1단계부터 다시 수행합니다.
37+
3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다.
38+
4. 문자열 u가 "올바른 괄호 문자열"이 아니라면 아래 과정을 수행합니다.
39+
4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다.
40+
4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다.
41+
4-3. ')'를 다시 붙입니다.
42+
4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다.
43+
4-5. 생성된 문자열을 반환합니다.
44+
</code></pre></div>
45+
<p><strong>"균형잡힌 괄호 문자열"</strong> p가 매개변수로 주어질 때, 주어진 알고리즘을 수행해 <strong>"올바른 괄호 문자열"</strong>로 변환한 결과를 return 하도록 solution 함수를 완성해 주세요.</p>
46+
47+
<h3>매개변수 설명</h3>
48+
49+
<ul>
50+
<li>p는 '(' 와 ')' 로만 이루어진 문자열이며 길이는 2 이상 1,000 이하인 짝수입니다.</li>
51+
<li>문자열 p를 이루는 '(' 와 ')' 의 개수는 항상 같습니다.</li>
52+
<li>만약 p가 이미 "올바른 괄호 문자열"이라면 그대로 return 하면 됩니다.</li>
53+
</ul>
54+
55+
<hr>
56+
57+
<h3>입출력 예</h3>
58+
<table class="table">
59+
<thead><tr>
60+
<th>p</th>
61+
<th>result</th>
62+
</tr>
63+
</thead>
64+
<tbody><tr>
65+
<td><code>"(()())()"</code></td>
66+
<td><code>"(()())()"</code></td>
67+
</tr>
68+
<tr>
69+
<td><code>")("</code></td>
70+
<td><code>"()"</code></td>
71+
</tr>
72+
<tr>
73+
<td><code>"()))((()"</code></td>
74+
<td><code>"()(())()"</code></td>
75+
</tr>
76+
</tbody>
77+
</table>
78+
<h3>입출력 예에 대한 설명</h3>
79+
80+
<p><strong>입출력 예 #1</strong><br>
81+
이미 "올바른 괄호 문자열" 입니다.</p>
82+
83+
<p><strong>입출력 예 #2</strong></p>
84+
85+
<ul>
86+
<li>두 문자열 u, v로 분리합니다.
87+
88+
<ul>
89+
<li>u = <code>")("</code></li>
90+
<li>v = <code>""</code></li>
91+
</ul></li>
92+
<li>u가 "올바른 괄호 문자열"이 아니므로 다음과 같이 새로운 문자열을 만듭니다.
93+
94+
<ul>
95+
<li>v에 대해 1단계부터 재귀적으로 수행하면 빈 문자열이 반환됩니다.</li>
96+
<li>u의 앞뒤 문자를 제거하고, 나머지 문자의 괄호 방향을 뒤집으면 <code>""</code>이 됩니다.</li>
97+
<li>따라서 생성되는 문자열은 <code>"("</code> + <code>""</code> + <code>")"</code> + <code>""</code>이며, 최종적으로 <code>"()"</code>로 변환됩니다.</li>
98+
</ul></li>
99+
</ul>
100+
101+
<p><strong>입출력 예 #3</strong></p>
102+
103+
<ul>
104+
<li>두 문자열 u, v로 분리합니다.
105+
106+
<ul>
107+
<li>u = <code>"()"</code></li>
108+
<li>v = <code>"))((()"</code></li>
109+
</ul></li>
110+
<li>문자열 u가 "올바른 괄호 문자열"이므로 그대로 두고, v에 대해 재귀적으로 수행합니다.</li>
111+
<li>다시 두 문자열 u, v로 분리합니다.
112+
113+
<ul>
114+
<li>u = <code>"))(("</code></li>
115+
<li>v = <code>"()"</code></li>
116+
</ul></li>
117+
<li>u가 "올바른 괄호 문자열"이 아니므로 다음과 같이 새로운 문자열을 만듭니다.
118+
119+
<ul>
120+
<li>v에 대해 1단계부터 재귀적으로 수행하면 <code>"()"</code>이 반환됩니다.</li>
121+
<li>u의 앞뒤 문자를 제거하고, 나머지 문자의 괄호 방향을 뒤집으면 <code>"()"</code>이 됩니다.</li>
122+
<li>따라서 생성되는 문자열은 <code>"("</code> + <code>"()"</code> + <code>")"</code> + <code>"()"</code>이며, 최종적으로 <code>"(())()"</code>를 반환합니다.</li>
123+
</ul></li>
124+
<li>처음에 그대로 둔 문자열에 반환된 문자열을 이어 붙이면 <code>"()"</code> + <code>"(())()"</code> = <code>"()(())()"</code>가 됩니다.</li>
125+
</ul>
126+
127+
128+
> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import java.util.*;
2+
3+
class Solution {
4+
int lCnt;
5+
int rCnt;
6+
String answer = "";
7+
String temp = "";
8+
public String solution(String p) {
9+
return recursion(p);
10+
}
11+
12+
String recursion(String p){
13+
if(p.length() == 0) return "";
14+
15+
String u = separationUV(p)[0];
16+
String v = separationUV(p)[1];
17+
if(isCorrect(u)) { // u가 올바른 문자열
18+
return u + recursion(v);
19+
} else{
20+
// 올바른 문자열이 아닌 경우
21+
v = "(" + recursion(v)+ ")";
22+
u = u.substring(1,u.length()-1); // 양 끝 문자 제거
23+
u = reverse(u);
24+
return v+u;
25+
}
26+
}
27+
28+
String reverse(String u){
29+
if(u.length() == 0) return "";
30+
StringBuilder sb = new StringBuilder();
31+
for(char ch : u.toCharArray()){
32+
if(ch == '(') sb.append(')');
33+
else sb.append('(');
34+
}
35+
return sb.toString();
36+
}
37+
38+
String[] separationUV(String p){
39+
lCnt =0;
40+
rCnt =0;
41+
StringBuilder u = new StringBuilder();
42+
StringBuilder v = new StringBuilder();
43+
for(char ch : p.toCharArray()){
44+
// 균형 잡힌 괄호 문자열 완성
45+
if(lCnt != 0 && lCnt == rCnt){
46+
v.append(ch);
47+
} else{
48+
if(ch == '(') {
49+
lCnt++;
50+
u.append(ch);
51+
} else {
52+
rCnt++;
53+
u.append(ch);
54+
}
55+
}
56+
}
57+
58+
return new String[]{u.toString(),v.toString()};
59+
}
60+
61+
boolean isCorrect(String u) {
62+
if(lCnt == rCnt && lCnt != 0) { // 균형이 맞고
63+
Stack<Character> stack = new Stack<>();
64+
for(char ch : u.toCharArray()){
65+
if(ch =='('){
66+
stack.push(ch);
67+
} else{
68+
// ')' 와의 짝인 '('이 stack에 있으면
69+
if(!stack.isEmpty() && stack.peek() == '('){
70+
stack.pop();
71+
continue;
72+
}
73+
return false;
74+
}
75+
}
76+
return true;
77+
}
78+
return false;
79+
}
80+
}

0 commit comments

Comments
 (0)