Lv2. 괄호 변환 Javascript
https://programmers.co.kr/learn/courses/30/lessons/60058
function checkCorrectArr(str) {
if (str[0] === ")") return false;
let leftCnt = 0;
let rightCnt = 0;
[...str].forEach((el) => {
if (leftCnt >= rightCnt) {
el === "(" ? leftCnt++ : rightCnt++;
} else {
return false;
}
});
return true;
}
function solution(p) {
if (!p) return "";
let answer = "";
let u = "";
let v = "";
let idx = 0;
let uLeftCnt = 0;
let uRightCnt = 0;
for (let i = 0; i < p.length; i++) {
p[i] === "(" ? uLeftCnt++ : uRightCnt++;
idx++;
if (uLeftCnt === uRightCnt) {
u = p.slice(0, idx);
v = p.slice(idx);
break;
}
}
if (checkCorrectArr(u)) {
answer += u;
answer += solution(v);
return answer;
} else {
answer += "(";
answer += solution(v);
answer += ")";
for (let i = 1; i < u.length - 1; i++) {
u[i] === "(" ? (answer += ")") : (answer += "(");
}
return answer;
}
}
괄호 문자열의 종류
- 균형잡힌 괄호 문자열 : 좌, 우 괄호의 숫자가 같을 경우,
- 올바른 괄호 문자열 : 균형잡힌 괄호 문자열 중, 괄호의 순서까지 맞는 경우
// 올바른 괄호 문자열인지 확인하는 함수
function checkCorrectArr(str) {
if (str[0] === ")") return false; // ")"로 시작하면 올바를 수가 없다.
let leftCnt = 0;
let rightCnt = 0;
[...str].forEach((el) => {
// leftCnt가 rightCnt보다 크거나 같을 경우 로직을 돌면서 cnt++
if (leftCnt >= rightCnt) {
el === "(" ? leftCnt++ : rightCnt++;
} else { // 예외 상황이면 올바르지 않은 괄호.
return false;
}
});
return true; // 예외 상황을 타지 않았으면 올바른 괄호.
}
function solution(p) {
// 1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다.
if (!p) return "";
let answer = "";
// 2. 문자열 w를 두 "균형잡힌 괄호 문자열" u, v로 분리합니다.
// 단, u는 "균형잡힌 괄호 문자열"로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다.
let u = "";
let v = "";
let idx = 0;
let uLeftCnt = 0;
let uRightCnt = 0;
// p를 돌면서 left와 right의 cnt를 올려주고,
// 두 값이 같아지는 순간, u와 v를 세팅하고 break
for (let i = 0; i < p.length; i++) {
p[i] === "(" ? uLeftCnt++ : uRightCnt++;
idx++;
if (uLeftCnt === uRightCnt) {
u = p.slice(0, idx);
v = p.slice(idx);
break;
}
}
if (checkCorrectArr(u)) {
// 3. 문자열 u가 "올바른 괄호 문자열" 이라면 문자열 v에 대해 1단계부터 다시 수행합니다.
// 3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다.
answer += u;
answer += solution(v);
return answer;
} else {
// 4. 문자열 u가 "올바른 괄호 문자열"이 아니라면 아래 과정을 수행합니다.
// 4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다.
// 4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다.
// 4-3. ')'를 다시 붙입니다.
// 4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다.
// 4-5. 생성된 문자열을 반환합니다.
answer += "(";
answer += solution(v);
answer += ")";
for (let i = 1; i < u.length - 1; i++) {
u[i] === "(" ? (answer += ")") : (answer += "(");
}
return answer;
}
}
풀이 과정을 알려주는 친절한 문제였지만, 중간중간 실수가 많아서 오래걸렸던 문제.
예외 사항에 대한 고찰이 더 필요
댓글 환영
질문 환영
by.protect-me