[Algorithm]Toy Problem 17

안정태·2021년 5월 15일
3

Algorithm

목록 보기
17/50
post-thumbnail

문제 : balancedBrackets

문자열을 입력받아 문자열 내의 모든 괄호의 짝이 맞는지 여부를 리턴해야 합니다.

다음 단계에 맞춰 함수를 작성해 보세요

  • 괄호의 종류를 단 한가지로 한정합니다.
  • 괄호의 종류를 늘려 모든 종류의 괄호에도 작동하도록 합니다.
  • 괄호를 제외한 문자열이 포함된 경우에도 작동하도록 합니다.
let output = balancedBrackets('(');
console.log(output); // // -> false

output = balancedBrackets('()');
console.log(output); // --> true

문제의 접근

함정인가...? 문제가 너무 쉽다고 생각했다. 단순하게 생각해서 문자열을 배열로 리턴해준뒤 배열을 순회하면서 열린 괄호 갯수랑 닫힌 괄호 갯수를 세서 같으면 짝이 맞고 다르면 짝이 다른거라 생각해보았다.

const balancedBrackets = function (str) {
  // TODO: 여기에 코드를 작성합니다.
  let open = '('
  let close = ')'

  let arr = str.split('')
  let openNum = 0;
  let closeNum = 0;

  for(let i = 0; i < arr.length; i++){
    if(arr[i] === open){
      openNum++;
    }
    if(arr[i] === close){
      closeNum++;
    }
  }

  if(openNum !== closeNum){
    return false;
  }

  return true;
};

이렇게하면 10/14를 통과하게 된다. 하지만 Advanced를 제외한다면 1개만 틀린 것인데 그 이유를 살펴보니 )( 이것 처럼 닫는게 먼저온다면 짝을 이룰 수가 없다.

때문에 if(arr[i] === close) 조건문 내부를 다음과 같이 조금만 수정하면 문제없이 통과가 된다.

if(arr[i] === close){
  if(openNum === 0 || openNum === closeNum){
    return false;
  }else{
    closeNum++;
  }
}

Advanced

모든 종류의 괄호(, ), {, }, [, ]가 포함된 문자열을 입력빋아 모든 괄호의 짝이 맞는지 여부를 리턴해 보세요.

let output = balancedBrackets('[](){}');
console.log(output); // --> true

output = balancedBrackets('[({})]');
console.log(output); // --> true

let output3 = balancedBrackets('[(]{)}');
console.log(output); // --> false

위 문제를 무사히 통과했다면 이 또한 크게 어렵지 않다. 단순하게 생각해서 {, }, [, ]를 추가해서 만들어주기만 하면 된다.

const balancedBrackets = function (str) {
  // TODO: 여기에 코드를 작성합니다.
  let arr = str.split('')

  let openNum1 = 0;
  let closeNum1 = 0;
  let openNum2 = 0;
  let closeNum2 = 0;
  let openNum3 = 0;
  let closeNum3 = 0;

  let open1 = '('
  let close1 = ')'
  let open2 = '{'
  let close2 = '}'
  let open3 = '{'
  let close3 = '}'


  for(let i = 0; i < arr.length; i++){
    if(arr[i] === open1){
      openNum1++;
    }
    if(arr[i] === close1){
      if(openNum1 === closeNum1){
        return false;
      }else{
        closeNum1++;
      }
    }

    if(arr[i] === open2){
      openNum2++;
    }
    if(arr[i] === close2){
      if(openNum2 === closeNum2){
        return false;
      }else{
        closeNum2++;
      }
    }

    if(arr[i] === open3){
      openNum3++;
    }
    if(arr[i] === close3){
      if(openNum3 === closeNum3){
        return false;
      }else{
        closeNum3++;
      }
    }
  }

  if(openNum1 !== closeNum1 || openNum2 !== closeNum2 || openNum3 !== closeNum3){
    return false;
  }

  return true;
};

13/14다. 치명적인 실수를 했다. let output3 = balancedBrackets('[(]{)}');이렇게 되는 경우는 갯수가 맞아도 결국 false인 것이다. 그렇다면 갯수를 세는게 목적이 아닌 열고 닫는다에 포커스를 맞춰서 생각해야 한다.

const balancedBrackets = function (str) {
  // TODO: 여기에 코드를 작성합니다.
  const arr = str.split('')
  const stack = [];
  const open1 = '(';
  const close1 = ')';
  const open2 = '{';
  const close2 = '}';
  const open3 = '[';
  const close3 = ']';

  for(let i = 0; i < arr.length; i++){
    if(arr[i] === open1) {
      stack.push(str[i]);
    }
    if (arr[i] === close1) {
      const target = stack.pop();
      if(target !== open1){
        return false;
      }
    }

    if(arr[i] === open2) {
      stack.push(str[i]);
    }
    if (arr[i] === close2) {
      const target = stack.pop();
      if(target !== open2){
        return false;
      }
    }

    if(arr[i] === open3) {
      stack.push(str[i]);
    }
    if (arr[i] === close3) {
      const target = stack.pop();
      if(target !== open3){
        return false;
      }
    }
  }

  return stack.length === 0;
};

그냥 여는거 나온 다음에 그 짝에 맞는 닫는게 나온지를 확인해서 리턴해주면 되는 거였다...

문제를 통해 생각해 볼 것

쉬운 문제였다. 진짜... 근데 문제 이해를 못해서 생각보다 조금 더 걸렸다. stack을 활용해야한다는 건 마지막 테스트케이스가 통과하지 못하는 걸 보고서야 알게 되었다.
문제가 좀더 직관적이었으면 좋겠다.

profile
코딩하는 펭귄

0개의 댓글