스택은 LIFO(Last In Firtst Out - 후입선출) 원리에 따라 정렬된 컬렉션이다.
스택의 자료는 항상 동일한 종단점에서 추가/삭제된다.
스택은 책더미를 연상하면 된다.
function stack() {
const items = [];
// push
this.push = function (element) {
items.push(element);
};
// pop
this.pop = function () {
return items.pop();
};
// peek
this.peek = function () {
return items[items.length - 1];
};
// isEmpty
this.isEmpty = function () {
return items.length === 0;
};
// size
this.size = function () {
return items.length;
};
// clear
this.clear = function () {
items = [];
};
// print
this.print = function () {
console.log(Number(items));
};
}
const stack = new Stack();
console.log(stack.isEmpty()); // true
stack에 push를 해줄 경우
stack.push(5);
stack.push(6);
stack.push(7);
console.log(stack.peek()); // 7
stack에 pop을 해줄 경우
stack.pop();
console.log(stack.peek()); // 6
위 그림은 10진수 233을 2진수로 변환하는 과정을 스택을 이용해 나타난 그림이다.
일반적으로 JS를 사용하는 사람들은 따로 구현을 해서 진수변환을 하는게 아니라, 아마 toString()을 사용할 것이다. - 나도 그렇다.
const dec = 233;
const bin = dec.toString(2); // "11101001"
그렇다면 메소드를 사용하지 않고 직접 구현을 한다면?
function divideBy2(decNumber) {
const remStack = new Stack();
let rem; // 나머지
let binaryString = ''; // 2진수
while (decNumber > 0) {
rem = Math.floor(decNumber % 2); // 나눗셈 몫이 0이 아닐 때까지
remStack.push(rem); // 나머지(rem)를 스택에 밀어 넣고
// 초기값 decNumber(여기서는 233)을 2로 나눈 '몫'으로 업데이트한다.
decNumber = Math.floor(decNumber / 2);
}
// remStack 배열(스택)이 텅 빌 때까지 원소를 pop 메소드로 꺼내어 문자열로 연결하면 2진수가 완성된다.
while (!remStack.isEmpty()) binaryString += remStack.pop().toString();
return binaryString;
}
결과를 확인해보면?
console.log(divideBy2(233)); // "11101001"
다른 진법으로도 변환이 가능할까?
function baseConverter(decNumber, base) {
const remStack = new Stack();
let rem;
let baseString = '';
// 변경 부분!
digits = '0123456789ABCDEF'; // 0~15까지를 나타내는 16진수의 숫자들
while (decNumber > 0) {
rem = Math.floor(decNumber % base);
remStack.push(rem);
decNumber = Math.floor(decNumber / base);
}
remStack.print() // 9,15,7,8,1
while (!remStack.isEmpty()) {
baseString += digits[remStack.pop()]; // 변경 부분!
}
return baseString;
}
// 10진수 -> 16진수
console.log(baseConverter(100345, 16)); // 187F9
같은 원리다. 다만, 10진수를 2진수로 바꿀 때는 나머지가 0 아니면 1이었다. 8진수로 바꾼다면 나머지는 0~7이 될 것이고, 16진수라면 숫자 0~9에 문자 A~F(10~15에 해당)까지 필요하다.
따라서 이런 값들을 바꾸는 로직이 추가되어야 한다. (변경 부분!을 확인해보자)