[JS] 덱

Yongmin Park·2024년 7월 22일
0

JS-Programmers

목록 보기
14/14

프로그래머스

자바스크립트로 덱(Deque) 구현하기 😃

안녕하세요, 여러분! 게임이나 알고리즘 문제를 풀다 보면 덱(Deque)을 사용해야 하는 경우가 꽤 있죠. 덱은 양쪽 끝에서 삽입과 삭제가 가능한 자료 구조입니다. 오늘은 자바스크립트를 사용해서 덱을 구현해볼 텐데요, 완전 초보자도 따라할 수 있도록 자세하게 설명해 드릴게요. 😉

입출력 오버헤드란?

먼저, 실제 코드 구현에 들어가기 전에 '입출력 오버헤드'라는 개념에 대해 잠깐 짚고 넘어가 볼까요? 입출력 오버헤드는 데이터의 입출력 과정에서 발생하는 추가적인 비용을 의미합니다. 특히 많은 양의 데이터를 다룰 때 입출력 오버헤드를 최소화하는 것이 중요합니다. 그래서 오늘 구현하는 덱에서도 이 부분을 고려할 것입니다.


덱 구현하기 🚀

자, 이제 본격적으로 덱을 구현해봅시다. 덱을 구현하려면 몇 가지 기본적인 명령들을 처리해야 합니다:

  1. push_front X: 정수 X를 덱의 앞에 넣습니다.
  2. push_back X: 정수 X를 덱의 뒤에 넣습니다.
  3. pop_front: 덱의 가장 앞에 있는 수를 빼고 그 수를 출력합니다. 덱이 비어 있다면 -1을 출력합니다.
  4. pop_back: 덱의 가장 뒤에 있는 수를 빼고 그 수를 출력합니다. 덱이 비어 있다면 -1을 출력합니다.
  5. size: 덱에 들어있는 정수의 개수를 출력합니다.
  6. empty: 덱이 비어 있으면 1을, 아니면 0을 출력합니다.
  7. front: 덱의 가장 앞에 있는 정수를 출력합니다. 덱이 비어 있으면 -1을 출력합니다.
  8. back: 덱의 가장 뒤에 있는 정수를 출력합니다. 덱이 비어 있으면 -1을 출력합니다.

이제 코드를 보면서 하나씩 살펴보겠습니다.

전체 코드

const [N, ...input] = require('fs')
  .readFileSync(0)
  .toString()
  .trim()
  .split('\n');

let deque = [];
let answer = [];
let l = 0;

for (let i = 0; i < N; i++) {
  [command, cnt] = input[i].split(' ');
  switch (command) {
    case 'push_front':
      deque.unshift(+cnt);
      l++;
      break;
    case 'push_back':
      deque.push(+cnt);
      l++;
      break;
    case 'pop_front':
      answer.push(l ? deque.shift() : -1);
      l--;
      l = l < 0 ? 0 : l;
      break;
    case 'pop_back':
      answer.push(l ? deque.pop() : -1);
      l--;
      l = l < 0 ? 0 : l;
      break;
    case 'size':
      answer.push(l);
      break;
    case 'empty':
      answer.push(l ? 0 : 1);
      break;
    case 'front':
      answer.push(l ? deque[0] : -1);
      break;
    case 'back':
      answer.push(l ? deque[l - 1] : -1);
      break;
  }
}

console.log(answer.join('\n'));

코드 설명

  1. 입력 처리

    const [N, ...input] = require('fs')
      .readFileSync(0)
      .toString()
      .trim()
      .split('\n');

    먼저, 표준 입력을 읽어옵니다. readFileSync(0)은 표준 입력(stdin)을 읽는 함수입니다. 가져온 데이터를 toString을 이용해 문자열로 변환하고, trim으로 양끝의 공백을 제거한 후, split로 줄바꿈(\n)을 기준으로 나눕니다. 첫 번째 줄은 명령의 수인 N이고, 나머지는 명령어들입니다.

  2. 변수 초기화

    let deque = [];
    let answer = [];
    let l = 0;

    deque는 덱을 저장할 배열입니다. answer는 결과를 저장할 배열입니다. l은 덱의 길이를 저장하는 변수입니다.

  3. 명령 수행

    for (let i = 0; i < N; i++) {
      [command, cnt] = input[i].split(' ');
      switch (command) {
        case 'push_front':
          deque.unshift(+cnt);
          l++;
          break;
        case 'push_back':
          deque.push(+cnt);
          l++;
          break;
        case 'pop_front':
          answer.push(l ? deque.shift() : -1);
          l--;
          l = l < 0 ? 0 : l;
          break;
        case 'pop_back':
          answer.push(l ? deque.pop() : -1);
          l--;
          l = l < 0 ? 0 : l;
          break;
        case 'size':
          answer.push(l);
          break;
        case 'empty':
          answer.push(l ? 0 : 1);
          break;
        case 'front':
          answer.push(l ? deque[0] : -1);
          break;
        case 'back':
          answer.push(l ? deque[l - 1] : -1);
          break;
      }
    }

    각 명령을 순차적으로 처리합니다. input[i].split(' ')를 이용해 명령과 값을 분리합니다. switch 문을 이용해 각각의 명령을 처리해줍니다.

    • push_front: unshift를 사용해서 배열의 앞에 값을 추가합니다.
    • push_back: push를 사용해 배열의 뒤에 값을 추가합니다.
    • pop_front: shift를 사용해 배열의 앞에서 값을 빼내고 출력합니다. 값이 없으면 -1을 출력합니다.
    • pop_back: pop을 사용해 배열의 뒤에서 값을 빼내고 출력합니다. 값이 없으면 -1을 출력합니다.
    • size: 배열의 길이를 출력합니다.
    • empty: 배열이 비어 있는지 여부를 출력합니다.
    • front: 배열의 첫 번째 값을 출력합니다. 값이 없으면 -1을 출력합니다.
    • back: 배열의 마지막 값을 출력합니다. 값이 없으면 -1을 출력합니다.
  4. 결과 출력

    console.log(answer.join('\n'));

    최종 결과는 answer 배열에 저장되어 있으므로, join을 이용해 줄바꿈(\n)을 기준으로 합쳐서 출력합니다.


이렇게 해서 자바스크립트로 덱을 구현해보았습니다! 😎 이제 여러분도 다양한 알고리즘 문제나 게임 로직에서 덱을 자유롭게 사용할 수 있을 거예요. 따라오시느라 고생 많으셨습니다. 다음에도 상세한 설명으로 다시 찾아뵐게요! 🤗

Happy Coding! 💻✨

profile
기록으로 기적을

0개의 댓글