안녕하세요, 여러분! 게임이나 알고리즘 문제를 풀다 보면 덱(Deque)을 사용해야 하는 경우가 꽤 있죠. 덱은 양쪽 끝에서 삽입과 삭제가 가능한 자료 구조입니다. 오늘은 자바스크립트를 사용해서 덱을 구현해볼 텐데요, 완전 초보자도 따라할 수 있도록 자세하게 설명해 드릴게요. 😉
먼저, 실제 코드 구현에 들어가기 전에 '입출력 오버헤드'라는 개념에 대해 잠깐 짚고 넘어가 볼까요? 입출력 오버헤드는 데이터의 입출력 과정에서 발생하는 추가적인 비용을 의미합니다. 특히 많은 양의 데이터를 다룰 때 입출력 오버헤드를 최소화하는 것이 중요합니다. 그래서 오늘 구현하는 덱에서도 이 부분을 고려할 것입니다.
자, 이제 본격적으로 덱을 구현해봅시다. 덱을 구현하려면 몇 가지 기본적인 명령들을 처리해야 합니다:
push_front X
: 정수 X
를 덱의 앞에 넣습니다.push_back X
: 정수 X
를 덱의 뒤에 넣습니다.pop_front
: 덱의 가장 앞에 있는 수를 빼고 그 수를 출력합니다. 덱이 비어 있다면 -1
을 출력합니다.pop_back
: 덱의 가장 뒤에 있는 수를 빼고 그 수를 출력합니다. 덱이 비어 있다면 -1
을 출력합니다.size
: 덱에 들어있는 정수의 개수를 출력합니다.empty
: 덱이 비어 있으면 1
을, 아니면 0
을 출력합니다.front
: 덱의 가장 앞에 있는 정수를 출력합니다. 덱이 비어 있으면 -1
을 출력합니다.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'));
입력 처리
const [N, ...input] = require('fs')
.readFileSync(0)
.toString()
.trim()
.split('\n');
먼저, 표준 입력을 읽어옵니다. readFileSync(0)
은 표준 입력(stdin)을 읽는 함수입니다. 가져온 데이터를 toString
을 이용해 문자열로 변환하고, trim
으로 양끝의 공백을 제거한 후, split
로 줄바꿈(\n
)을 기준으로 나눕니다. 첫 번째 줄은 명령의 수인 N
이고, 나머지는 명령어들입니다.
변수 초기화
let deque = [];
let answer = [];
let l = 0;
deque
는 덱을 저장할 배열입니다. answer
는 결과를 저장할 배열입니다. l
은 덱의 길이를 저장하는 변수입니다.
명령 수행
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
을 출력합니다.결과 출력
console.log(answer.join('\n'));
최종 결과는 answer
배열에 저장되어 있으므로, join
을 이용해 줄바꿈(\n
)을 기준으로 합쳐서 출력합니다.
이렇게 해서 자바스크립트로 덱을 구현해보았습니다! 😎 이제 여러분도 다양한 알고리즘 문제나 게임 로직에서 덱을 자유롭게 사용할 수 있을 거예요. 따라오시느라 고생 많으셨습니다. 다음에도 상세한 설명으로 다시 찾아뵐게요! 🤗
Happy Coding! 💻✨