๋ฐ์ดํฐ๋ฅผ ์์๋๋ก ์๋ ์๋ฃ๊ตฌ์กฐ๋ก, ์ ์ถ๋ ฅ์ด ํ๋์ ๋ฐฉํฅ์ผ๋ก ์ด๋ฃจ์ด์ง๋ ์ ํ์ ์ ๊ทผ์ด ํน์ง์ด๋ค. ๋ฐ๋ผ์ ๊ฐ์ฅ ๋จผ์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ๋ ๊ฐ์ฅ ๋์ค์ ๋์ฌ ์ ์๊ณ (FILO), ๋ฐ๋๋ก ๊ฐ์ฅ ๋์ค์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ๋ ๊ฐ์ฅ ๋จผ์ ๋์ฌ ์ ์๋ค(LIFO).
์ด ๋, Stack์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ๋ ๊ฒ์ push
, ๊บผ๋ด๋ ๊ฒ์ pop
์ด๋ผ๊ณ ํ๋ค.
Stack์ ํน์ง์ ์ ๋ฆฌํ์๋ฉด, ์๋์ ๊ฐ๋ค.
LIFO(Last In First Out)
๋ฐ์ดํฐ๊ฐ ์๋ฌด๋ฆฌ ๋ง์๋ ํ๋์ฉ ๋ฃ๊ณ ๋บ ์ ์๋ค.
(ํ๊บผ๋ฒ์ ์ฌ๋ฌ๊ฐ X)
ํ๋์ ์ ์ถ๋ ฅ ๋ฐฉํฅ
์ ์ฅ๋๋ ๋ฐ์ดํฐ๋ ์ ํํ๋ฉฐ ์ ์ ์ด๋ค.
์คํ์ ํฌ๊ธฐ๋ ์ ํ๋์ด์๋ค.(์คํ ์ค๋ฒํ๋ก ์์ฃผ ๋ฐ์)
class Stack {
constructor() {
this.storage = {};
this.top = 0; // Stack์ ์ต์๋จ์ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ ๋ณ์(0์ผ๋ก ์ด๊ธฐํ)
}
// stack์ size
// this.top = Stack์ด ์์ผ ๋๋ง๋ค ++,
// this.top = Stack์ ์๋กญ๊ฒ ์ถ๊ฐ๋ ์์์ index,(top์ ๊ฐ์ size์ ๋์ผ)
size() {
return this.top;
}
// stack์ element(๋ฐ์ดํฐ)์ถ๊ฐ
// key : ์๋กญ๊ฒ ์ถ๊ฐ๋ element์ index๋ฅผ ๋ํ๋ด๋ this.top
// value : element
// key์ value๋ฅผ storage์ ํ ๋นํ๊ณ , this.top์ ๋ค์ ์ธ๋ฑ์ค๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ํ์ฌ ์๋ก์ด element์ ๋๋น
push(element) {
this.storage[this.top] = element;
this.top += 1;
}
// ๊ฐ์ฅ ๋์ค์ ์ถ๊ฐ๋ ๋ฐ์ดํฐ๊ฐ ๊ฐ์ฅ ๋จผ์ ๋์์ผ ํ๋ค.
// stack์์ element๋ฅผ ์ ๊ฑฐํ ๋ค, ํด๋น element๋ฅผ return.
// ๋ง์ฝ size๊ฐ 0์ด๋ผ๋ฉด ์๋ฌด๊ฒ๋ return ํ์ง ์๋๋ค.
// top-1(๊ฐ์ฅ ๋์ค์ ์ถ๊ฐ๋ ๋ฐ์ดํฐ๊ฐ ์๋ index)๋ก ์ต์๋จ์ ์ค์ ํ ํ ๋ณ์์ ์ ์ฅํ๊ณ , Stack์์ ์ ๊ฑฐ.
// ํ๋๋ฅผ ์ ๊ฑฐํ์ผ๋ top-1.
pop() {
if (this.size() <= 0) {
return;
}
const result = this.storage[this.top-1];
delete this.storage[this.top-1];
this.top -= 1;
return result;
}
}
// ์
์ถ๋ ฅ
const stack = new Stack();
stack.size(); // 0
for(let i = 1; i < 10; i++) {
stack.push(i);
}
stack.pop(); // 9
stack.pop(); // 8
stack.size(); // 7
stack.push(8);
stack.size(); // 8
...
๋ธ๋ผ์ฐ์ ์์ Stack์ด ์ฌ์ฉ๋ ๋, ์๋์ ์์๋ฅผ ๊ฑฐ์น๋ค.
์๋ก์ด ํ์ด์ง ์ ์ -> ํ์ฌ ํ์ด์ง๋ฅผ prev Stack์ ๋ณด๊ด
๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ -> ํ์ฌ ํ์ด์ง๋ฅผ Next Stack์ ๋ณด๊ด, ํ์ฌ ํ์ด์ง๋ก Prev Stack์ ๊ฐ์ฅ ๋์ค์ ๋ณด๊ด๋ ํ์ด์ง๋ฅผ ๊ฐ์ ธ์ด
์์ผ๋ก ๊ฐ๊ธฐ ๋ฒํผ -> Next Stack์ ๊ฐ์ฅ ๋ง์ง๋ง์ผ๋ก ๋ณด๊ด๋ ํ์ด์ง๋ฅผ ๊ฐ์ ธ์ด, ํ์ฌ ํ์ด์ง๋ฅผ Prev Stack์ ๋ณด๊ด
function browserStack(actions, start) {
// start๊ฐ string์ด ์๋๋ฉด return false
if(typeof start !== 'string'){
return false;
}
// ๋ค๋ก ๊ฐ๊ธฐ, ํ์ฌ, ์์ผ๋ก ๊ฐ๊ธฐ stack์ ๋ณ์ ์ค์
let prev = [];
let now = start;
let next = [];
// actions ๋ฐฐ์ด์ ์ ๋ถ ํ์
for(let action of actions){
// ๋ง์ฝ actions์ ์์๊ฐ -1์ด๊ณ (๋ค๋ก๊ฐ๊ธฐ), prevStack์ ๊ธธ์ด๊ฐ 0์ด ์๋ ๋(์ด์ ์ผ๋ก ๋์๊ฐ๋ ํ์ด์ง๊ฐ ์๋ค๋ฉด)
if(action === -1 && prev[0]){
// ์ง๊ธ ๋ณด๊ณ ์๋ ํ์ด์ง๋ฅผ next์ ๋ฃ๊ณ
next.push(now);
// prev์์ ๊ฐ์ฅ ๋ง์ง๋ง ์์ ๊บผ๋ด์์ ํ์ฌ ํ์ด์ง์ ํ ๋น
now = prev.pop()
//๋ง์ฝ actions์ ์์๊ฐ 1์ด๊ณ (์์ผ๋ก ๊ฐ๊ธฐ), nextStack์ ๊ธธ์ด๊ฐ 0์ด ์๋ ๋(๋ค์์ผ๋ก ๋์ด๊ฐ๋ ํ์ด์ง๊ฐ ์๋ค๋ฉด)
}else if(action === 1 && next[0]){
// ์ง๊ธ ๋ณด๊ณ ์๋ ํ์ด์ง๋ฅผ prev์ ๋ฃ๊ณ
prev.push(now);
// next์์ ๊ฐ์ฅ ๋ง์ง๋ง ์์ ๊บผ๋ด์์ ํ์ฌ ํ์ด์ง์ ํ ๋น
now = next.pop();
// ๋ง์ฝ actions ๋ฐฐ์ด์ ์์๊ฐ string์ด๋ผ๋ฉด (์๋ก์ด ํ์ด์ง๋ผ๋ฉด)
}else if(typeof action === 'string'){
// ๋ด๊ฐ ๋ณด๊ณ ์๋ ํ์ด์ง๋ prev์ ๋ฃ์ด์ฃผ๊ธฐ
prev.push(now);
// action์ผ๋ก ๋ค์ด์จ ํ์ด์ง๊ฐ ํ์ฌ ํ์ด์ง๊ฐ ๋จ
now = action
// ์๋ก์ด ํ์ด์ง๋ ์์ผ๋ก ๊ฐ ์ ์์ผ๋ฏ๋ก next ์คํ์ ๋น์์ผ ํจ
next = [];
}
}
// ๋ฐฐ์ด์ stack์ ๋ณ์๋ฅผ ์์๋๋ก ๋ด์์ return
return [prev, now, next]
}
// ์
์ถ๋ ฅ
const actions = ["B", "C", -1, "D", "A", -1, 1, -1, -1];
const start = "A";
const output = browserStack(actions, start);
console.log(output); // [["A"], "B", ["A", "D"]]
const actions2 = ["B", -1, "B", "A", "C", -1, -1, "D", -1, 1, "E", -1, -1, 1];
const start2 = "A";
const output2 = browserStack(actions2, start2);
console.log(output2); // [["A", "B"], "D", ["E"]]
Reference: ์ฝ๋์คํ ์ด์ธ