개발 공부/알고리즘 문제 풀이

[프로그래머스] 괄호 변환 (JavaScript)

종범2 2020. 6. 6. 22:39

문제

프로그래머스 2020 KAKAO BLIND RECRUITMENT 괄호 변환

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

 

코딩테스트 연습 - 괄호 변환

카카오에 신입 개발자로 입사한 콘은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를 컴�

programmers.co.kr

언어

바스크립트(JavaScript)

 

접근 방법

  1. 변환 과정을 그대로 따르도록 코드를 작성한다. 변환 과정은 재귀적인 과정이다. 이때 과정을 실행할 문자열과 정답으로 출력할 문자열을 입력으로 받는 재귀 함수를 이용한다.
  2. 처음 문자열을 균형 잡힌 괄호 문자열 u, v로 분리한다. u는 더 나눌 수 없는 균형 잡힌 괄호 문자열이다. 문자열을 하나씩 탐색하면서 처음으로 ')'가 나온 수와 와 '('가 나온 수가 같으면 그때까지 탐색한 문자열이 u, 그 이후 문자열이 v가 된다.
  3. u가 올바른 문자열인지 확인한다. 문자열을 탐색하면서 '('가 나온 수보다 ')'가 나온 수가 더 많아지는 경우가 한 번이라도 나온다면 그 문자는 올바른 문자열이 아니다. u가 올바른 문자열이면 ans에 u를 붙이고 v부터 재귀 함수를 다시 호출한다. v가 비었다면 재귀 함수를 호출하지 않고 ans를 반환한다.
  4. u가 올바른 문자열이 아니라면 주어진 과정을 진행하고 ans를 반환한다.

코드

const TYPE1 = '\('
const TYPE2 = '\)'
function solution(p) {
    let result = convert(p,'');
    return result;
}
function convert(w,ans){
    // 문자열을 균형잡힌 괄호 문자열 u,v로 분리
    // u는 더 나눌 수 없는 균형잡힌 괄호 문자열
    let str = divide(w);
    let u = str[0];
    let v = str[1];
    if (check(u)){
        // u가 올바른 문자열이라면 ans에 u를 붙이고 v부터 다시 시작
        // v가 비어있다면 그동안 붙인 ans 반환
        ans += u;
        if (v===''){
            return ans;
        }
        return convert(v,ans);
    }else{
        // u가 올바른 문자열이 아니라면 과정 수행하고 반환
        ans += '\(' + convert(v,'') +'\)' + transfromU(u);
        return ans;
    }
}
function transfromU(u){
    let newU = ''
    for (let i=1; i<u.length-1; i++){
        if(u[i]===TYPE1){
            newU += TYPE2;
        }else{
            newU += TYPE1;
        }
    }
    return newU;
}
function check(str){
    // 문자열 넘기면서 TYPE1 문자열 개수보다 TYPE2 문자열 개수가 많아지면 올바른 문자열이 아님
    let isCorrect = true;
    let cntType1 = 0;
    let cntType2 = 0;
    for (let i=0; i<str.length; i++){
        if (str[i] === TYPE1){
            cntType1++;
        }else if (str[i] === TYPE2){
            cntType2++;
        }
        if (cntType1 < cntType2){
            isCorrect = false;
        }
    }
    return isCorrect;
}
function divide(str){
    // 문자열 넘기면서 처음으로 TYPE1 문자열 개수와 TYPE2 문자열 개수가 같아지면
    // 그동안 넘긴 문자열과 그 이후로 나누기
    let cntType1 = 0;
    let cntType2 = 0;
    let i = 0;
    for (i=0; i<str.length; i++){
        if (str[i] === TYPE1){
            cntType1++;
        }else if (str[i] === TYPE2){
            cntType2++;
        }
        if (cntType1 === cntType2){
            break;
        }
    }
    let arr = [];
    arr.push(str.substr(0,i+1));
    arr.push(str.substr(i+1,str.length-i));
    return arr;
}

복기

  1. 재귀 함수를 자유롭게 사용할 줄 알아야 한다. 바로바로 어떻게 사용해야 할지 떠오르지가 않아 시간이 오래 걸렸다.