알고리즘 문제 풀기

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

Solu- 2021. 8. 23. 16:00

링크

나의 코드

function solution(p = '') {
  if (!p) {
    return ''; // 빈 문자열 반환
  }

  let startCount = 0; // 여는 태그 갯수
  let endCount = 0; // 닫는 태그 갯수

  let u = '';
  let v = '';
  let check = 0;  // u가 올바른 괄호 문자열인지 확인하는 변수. 올바르다면 0
  for (let i = 0; i < p.length; i++) {

    if (p[i] === '(') {
      startCount++;
      check++;
    } else {
      endCount++;
      (check !== 0) && check--; // 0이 아닐 때만 -
    }

    if (startCount === endCount) {
      v = solution(p.substring(i + 1));

      // 문자열 u에 대한 검증 실시
      if (check !== 0) {
        // 4. u가 올바른 괄호 문자열이 아니라면

        u = p.substring(1, i).split('').reduce((pre, value) => {
          return pre + ((value === '(') ? ')' : '(');
        }, ''); // 앞뒤 글자 제거하고, 가운데를 뒤집었습니다.

        return '(' + v + ')' + u;

      } else {
        // u가 올바른 괄호 문자열일 경우
        u = p.substring(0, i + 1);

        return u + v; // 3-1. 수행한 문자열을 u에 이어붙인 후 반환
      }
    }
  }
}

문제에서 주어진 요구대로 풀었다. 이 괄호가 올바른 괄호 문자열인가 검증하는 과정이 지저분해서, 더 깔끔했으면 좋았을듯 하다.

모범 답안

function reverse(str) {
  return str.slice(1, str.length - 1).split("").map((c) => (c === "(" ? ")" : "(")).join("");
}

function solution(p) {
  if (p.length < 1) return "";

  let balance = 0;
  let pivot = 0;
  do { balance += p[pivot++] === "(" ? 1 : -1 } while (balance !== 0);

  const u = p.slice(0, pivot);
  const v = solution(p.slice(pivot, p.length));

  if (u[0] === "(" && u[u.length - 1] == ")") return u + v;
  else return "(" + v + ")" + reverse(u);
}

코드가 간결해진 게 보인다. do-while문으로 u와 v를 구분했는데, 이렇게 깔끔하게 표현될 수 있음이 대단하다. (0이 false로 반환됨을 잘 처리했다.)

또한 u가 올바른 괄호 문자열인지 검증하는 과정을 if (u[0] === "(" && u[u.length - 1] == ")")로 처리했다. 위의 과정에서 올바르게 짝이 맞는지 검증했기 때문에, 시작 문자만 (인지 확인해주면 구분이 가능했다. 따라서 해당 검증 코드를 한 번 더 정리하면

return (u[0] === '(') ? (u + v) : ('(' + v + ')' + reverse(u));

로 할 수 있다. 문제에 대한 이해도가 더 좋다면 코드를 더 간결하게 짤 수 있었다. 문제를 이해하는데 더욱 노력해야겠다.