ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CodeKata] 프로그래머스: 2.22(월), 멀쩡한 사각형
    Algorithm 2021. 2. 22. 12:37
    반응형

    🥋 Ooooth!! (Level 2) : 멀쩡한 사각형

    코드카타는 계속된다! 문제는 많은데 진도가 늦어 이번주부터는 토요일까지 주 6회로 풀려고 한다.

    또한, 저번주에 풀이들이 길어지는 것을 느껴, 최대한 지양하고 싶었지만 우선 일단위로 포스팅하는 것으로 조정해보았다.

     

    카카오답게 문제가 매우 길지만, 재귀함수를 통해 괄호쌍을 조정하여 '올바른 괄호 문자열' 로 가공하는 문제이다.

    문제의 '용어의 정의' 부분에 로직이 설명되어 있어서, 이를 그대로 코드화하는 데 우선 집중했다.

     

    🧮 풀이

    function divider(str) {
      let compareCount = 1;
      for (let i = 1 ; i < str.length ; i++) {
        compareCount = str[i] === str[0] ? compareCount += 1 : compareCount-= 1;
        if (compareCount === 0) {
          return { u: str.slice(0, i+1), v: str.slice(i+1) }
        }
      }
    }
    
    function isPair(str) {
      let stack = [];
      for (let i = 0 ; i < str.length ; i++) {
        if (str[i] === '(') {
          stack.push(str[i])
        }
        else {
          stack.pop()
        }
      }
      return stack.join('') === '';
    }
    
    function solution(p) {
      if (p === '') {
          return '';
      }
      if (isPair(p)) {
        return p;
      }
      else {
        const { u, v } = divider(p);
        let answer;
        if (!isPair(u)) {
          answer = '(' + solution(v) + ')';
          for (i=1 ; i < u.length-1 ; i++) {
            answer += u[i] === '(' ? ')' : '(';
          }
        }
        else {
          answer = u + solution(v)
        }
        return answer
      }
    }

    1. 개별기능 함수 만들기

    • divider(): 괄호 문자열을 인자로 받아 u(균형잡힌 괄호 문자열), v(나머지) 로 잘라주는 함수, 비구조화를 위해 객체로 반환
    • isPair(): 괄호 문자열이 균형잡힌 괄호 문자열인지 검사하는 boolean 함수, 균형이 안맞다면 stack 에 '(' 남게됨

    2. 괄호 문자열(p) '균형잡힌 괄호 문자열' 확인

    • p가 빈 문자열일 때 예외처리를 해준다. ('' 대신 p 반환해도 됨. isPair() 검사와 if로 묶어 p를 반환해도되나 직관성을 위해 분리)
    • isPair() 검사를 통해, p가 균형잡힌 괄호 문자열이라면 바로 반환하고 종료하면 된다.

    3. 괄호 문자열(p) 분할 및 가공

    • 아니라면, divider() 를 통해 p를 u, v로 분리해준다.(비구조화) answer는 문제로직에 따라 가공될 새로운 괄호 문자열
    • u가 isPair() 거짓인 경우, '(' + v에 대한 재귀 + ')' 순으로 더한다. (solution(v)를 통해 solution() 함수를 재귀함수로 활용)
    • 이후, u의 양 끝을 제외한 나머지 괄호를 뒤집어서 더해야하므로, 1 ~ (length-1) 전까지 순회하며 위처럼 뒤집었다.
    • u가 isPair() 참인 경우, u와 v에 대한 재귀를 더한 값이 answer 가 된다.

     

    🖇 리뷰

    function solution(p){
      if(p === "")
        return p;
      
      let leftBrkNum = 0;
      let rightBrkNum = 0;
      let pIdx = 0;
      let result = '';
      let isRight = true;
    
      do{
        if(p[pIdx] === '(')
          leftBrkNum++;
        else
          rightBrkNum++;
        if(rightBrkNum > leftBrkNum)
          isRight = false;
        pIdx++;
      }while(leftBrkNum !== rightBrkNum)
    
      let u = p.substr(0, pIdx);
      let v = p.substr(pIdx);
    
      if(isRight){
        return u + solution(v);
      }
      else{
      u = u.substr(1,u.length-2).replace(/[\(]|[\)]/g, (a) => a === ')' ? '(' : ')');
      v = `(${solution(v)})`;
        return v + u;
      }
    }

    * 출처: taesung 님의 블로그 (taesung1993.tistory.com/m/28?category=868017 )

     

    전반적인 풀이는 크게 다르지 않다.

    균형잡힌 괄호 문자열을 확인하기 위해 위처럼 do - while 반복문을 사용하는 방법도 있다는 것을 알았다.

    또한, 정규식 + replace() 조합을 통해 괄호 방향을 바꾼 것이 매우 좋은 방법이라고 생각한다.

     

     

    좋은 풀이도 많이 있었지만, 나 역시 문제에 제시된 기능들을 각각 함수화하고 재귀를 활용해 푼 점이 매우 뿌듯하여 리뷰를 이정도로 마치겠다. 😃😃

    반응형
Designed by Tistory.