본문 바로가기
문제풀이/프로그래머스

대중소괄호 짝 맞추기

by dev_kong 2021. 11. 26.
728x90
728x90

우리집 시니어가 추천해준 문제

프로그래머스에서는 문제가 지워진 듯 하다.

블로그들에 남아있던 문제 보고 풀었음

 

문제 설명

여섯 가지 괄호 '(', ')', '{', '}', '[', ']'로 이루어진 문자열이 바르게 닫힌 문자열인지 알아보려 합니다. 바르게 닫힌 문자열이라는 것은

'(' 문자로 열렸으면 반드시 짝지어서 ')' 문자로,
'[' 문자로 열렸으면 반드시 짝지어서 ']' 문자로,
'{' 문자로 열렸으면 반드시 짝지어서 '}' 문자로
닫히는 문자열입니다. 또한, 괄호 쌍 안에는 다른 괄호 쌍이 들어갈 수 있습니다. 예를 들어,

{{}}, ({})[]는 바르게 닫힌 괄호입니다.
[), ]()[, ([())]는 바르게 닫히지 않은 괄호입니다.
문자열 s가 주어졌을 때, 문자열 s가 바르게 닫힌 괄호이면 true를, 그렇지 않으면 false를 return 하는 solution 함수를 완성해 주세요.

제한사항
문자열 s는 (, ), {, }, [, ] 로만 이루어졌습니다.
문자열 s의 길이는 1 이상 40 이하입니다.

 

접근방법

https://kong-dev.tistory.com/31

 

올바른 괄호

문제 설명 괄호가 바르게 짝지어졌다는 것은 '(' 문자로 열렸으면 반드시 짝지어서 ')' 문자로 닫혀야 한다는 뜻입니다. 예를 들어 "()()" 또는 "(())()" 는 올바른 괄호입니다. ")()(" 또는 "(()(" 는 올

kong-dev.tistory.com

아까 이 문제의 심화 버전이다.

우선 스택을 이용해야 한다 했으니

pop과 push를 이용한다.

그럼 stack이라는 빈 배열 하나 짜놓고

for of 돌린다.

문자열은 유사배열객체(=배열조무사)라서 for문 돌아간다.

if로 여는괄호 ( { [ 셋 중 하나 들어오면

들어온 괄호 push로 넣어준다.

닫는 괄호가 들어오면, stack에 들어온 마지막 괄호랑 짝이 맞는질 확인해줘야 되는데,

이 부분이 고민이었다.

if else 세번 쓰면 되긴 하는데..

뭔가 그러기 싫다.

그렇게 안하고 하는 방법이 있을텐데.....

function checkBlank(s) {
  const checkList = ['(', ')', '{', '}', '[', ']'];
  let stack = [];
  
  for (const bracket of string) {
    if (bracket === '(' || bracket === '{' || bracket === '[') {
      stack.push(bracket);
    } else {
      if (stack[stack.length - 1] === checkList[checkList.indexOf(bracket) - 1]) {
        stack.pop();
      } else return false;
    }
  }
  return stack.length === 0 ? true : false;
  }

그렇게 해서 나온 방법

checkList라는 배열을 하나 만들어줬다.

여는 괄호의 다음 에는 짝이 맞는 닫는 괄호가 나오게끔 만들었다.

그래서 for of로 설정해놓은 bracket에 닫는 괄호가 들어오면

stack 배열에 들어있는 마지막 값과,

check기준 으로 bracket 앞에 있는 값과 비교하여

일치하면 pop으로 빼낸다.

(두번째 if문의 우변은 체크리스트에서 bracket의 위치를 확인후, 그 위치 앞에 위치한 괄호를 출력한다)

일치하지 않는다면 false를 리턴한다.

for문이 끝난뒤에 stack.length가 0이 아니면 false를 리턴 0이면 true를 리턴한다.

 

마지막에 length 오타나서 계속 false가 떴는데,

오타를 발견 못하고 계속 다른데서 원인을 찾다가 거의 한시간을 보냈다.

 

function checkBlank2(s) {
  const checkList = { ')': '(', '}': '{', ']': '[' };
  const stack = [];

  for (const bracket of s) {
    if (['(', '{', '['].includes(bracket)) {
      stack.push(bracket);
      continue;
    }

    if (stack.length === 0) return false;
    const lastBracket = stack.pop();

    if (lastBracket !== checkList[bracket]) {
      return false;
    }
  }

  return true;
}

 

이건 우리집 시니어랑 리팩토링 한 코드

우선 가장 큰 차이점은 배열이아닌 객체로 checkList를 만들었다!

3번째 if문에서 그 진가가 드러나는데

우변의 checkList[bracket] 이 

내가짠코드의 checkList[checkList.indexOf(bracket) - 1] 과 같은 역할이다!

내 코드는 내가봐도 뭐더라... 싶을 정도로 가독성이 안좋지만,

위의 코드는 간결해서 가독성이 좋다!

 

그리고 첫번째 if문에서 continue 를 사용했다.

내가 짠 코드는 

else 안에 다시 if랑 else를 넣어서 코드가 조금 복잡하게 보이는데

이렇게 하니까 굉장히 깔끔하다.

 

마지막으로 stack의 마지막 값과 비교를 하는게 아니라

stack의 마지막 값을 pop으로 빼낸 걸 변수에 할당해서 

그 변수와 checkList[bracket] 을 비교해서 

다르면 false를 리턴한다.

코드가 굉장히 쌈빡하고 깔끔하고

가독성 좋아졌다.

나도 이런 코드를 짜고 싶다.

계속 좋은 코드를 짜기 위해 생각해야겠다.

728x90
728x90

'문제풀이 > 프로그래머스' 카테고리의 다른 글

프린터  (0) 2021.11.29
기능개발  (0) 2021.11.27
올바른 괄호  (0) 2021.11.26
문자열 다루기 기본  (0) 2021.11.24
자릿수 더하기  (0) 2021.11.24

댓글