[백준] 9012 괄호 Node.js

Janet·2023년 10월 8일
0

Algorithm

목록 보기
268/314

문제

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고 부른다. 한 쌍의 괄호 기호로 된 “( )” 문자열은 기본 VPS 이라고 부른다. 만일 x 가 VPS 라면 이것을 하나의 괄호에 넣은 새로운 문자열 “(x)”도 VPS 가 된다. 그리고 두 VPS x 와 y를 접합(concatenation)시킨 새로운 문자열 xy도 VPS 가 된다. 예를 들어 “(())()”와 “((()))” 는 VPS 이지만 “(()(”, “(())()))” , 그리고 “(()” 는 모두 VPS 가 아닌 문자열이다.

여러분은 입력으로 주어진 괄호 문자열이 VPS 인지 아닌지를 판단해서 그 결과를 YES 와 NO 로 나타내어야 한다.

입력

입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 주어진다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫째 줄에는 괄호 문자열이 한 줄에 주어진다. 하나의 괄호 문자열의 길이는 2 이상 50 이하이다.

출력

출력은 표준 출력을 사용한다. 만일 입력 괄호 문자열이 올바른 괄호 문자열(VPS)이면 “YES”, 아니면 “NO”를 한 줄에 하나씩 차례대로 출력해야 한다.

예제 입력 1

6
(())())
(((()())()
(()())((()))
((()()(()))(((())))()
()()()()(()()())()
(()((())()(

예제 출력 1

NO
NO
YES
NO
YES
NO

예제 입력 2

3
((
))
())(()

예제 출력 2

NO
NO
NO

문제풀이

✅ 답안 #1

  • 스택을 활용하여 열린 괄호 '('를 만나면 스택에 push하고, 닫힌 괄호 ')'를 만나면 스택에서 pop하여 짝이 맞는지 검사합니다. 모든 문자열을 검사한 후 스택이 비어있으면 올바른 괄호 문자열로 판단하고 'YES'를, 그렇지 않으면 'NO'를 출력
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
let [n, ...input] = require('fs').readFileSync(filePath).toString().trim().split('\n');

const solution = (str) => {
  const stack = [];
  for (let i = 0; i < str.length; i++) {
	// str[i] === '('인 경우
    if (str[i] === '(') {
      stack.push('(');

    // str[i] === ')'인 경우
    } else {
      // 스택에 요소가 있는 경우 제거, 없는 경우 짝이 맞지 않으므로 즉시 'NO'반환
      if (stack.length) stack.pop();
      else return 'NO';
    }
  }
  // 스택에 요소 있는 경우 'NO'반환, 요소 없는 경우 짝이 맞는 것이므로 'YES'반환
  if (stack.length) return 'NO';
  else return 'YES';
};

const result = [];
for (let i = 0; i < input.length; i++) {
  result.push(solution(input[i]));
}
console.log(result.join('\n'));

✅ 답안 #2

  • ‘(’ 와 ‘)’의 개수를 체크하여 ‘(’이면 +1, ‘(’이면 -1을 하여 합이 0이 되면 개수는 맞다는 뜻이다 하지만, 개수만 맞다고 해서 올바른 괄호는 아니다 예를 들어, ‘())(’인 경우 괄호의 순서 및 조합이 올바르지 않기 때문이다. 따라서, ‘(’이 오지 않았는데, ‘)’가 먼저 온다거나 단독으로 ‘)’만 있는 경우에는 그 즉시 ‘NO’로 분류되어야 한다.
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt';
let [n, ...input] = require('fs').readFileSync(filePath).toString().trim().split('\n');

const result = [];

for (let i = 0; i < n; i++) {
  let count = 0;
  for (let str of input[i]) {
    str === '(' ? count++ : count--;
    
		// 카운트가 -1이 될 경우 ')'가 단독으로 있는 경우 이므로 중단
		if (count < 0) break;
  }
  // 0인 경우 YES, 0이 아닌 경우 NO
  result.push(!count ? 'YES' : 'NO');
}

console.log(result.join('\n'));
profile
😸

0개의 댓글