๊ฐ์ข ์๋ฃ๊ตฌ์กฐ๋ค๋ 'ํด๋์ค'์ด๋ค.
๊ฐ๋ น C#์ stack ํด๋์ค๋ ๋ค์ ๋งํฌ์ ๊ฐ๋ค.
https://docs.microsoft.com/ko-kr/dotnet/api/system.collections.stack?view=net-6.0
Stack ํด๋์ค (System.Collections)
์ ๋ค๋ฆญ์ด ์๋ ๊ฐ์ฒด์ ๊ฐ๋จํ LIFO(Last In First Out: ๋ง์ง๋ง์ ๋ค์ด๊ฐ ๊ฒ๋ถํฐ ์ฌ์ฉ) ์ปฌ๋ ์ ์ ๋ํ๋ ๋๋ค.
docs.microsoft.com
Stack ํด๋์ค
์ ์
์ ๋ค๋ฆญ์ด ์๋ ๊ฐ์ฒด์ ๊ฐ๋จํ LIFO(Last In First Out: ๋ง์ง๋ง์ ๋ค์ด๊ฐ ๊ฒ๋ถํฐ ์ฌ์ฉ) ์ปฌ๋ ์ ์ ๋ํ๋ ๋๋ค.
public class Stack : ICloneable, System.Collections.ICollection
์์ Object -> Stack
๊ตฌํ ICollection IEnumerable ICloneable
์์
๋ค์ ์์ ์์๋ Stack์ ๊ฐ์ ๋ง๋ค๊ณ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ๊ณผ ํด๋น ๊ฐ์ ํ์ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ ์์ต๋๋ค.
using System;
using System.Collections;
public class SamplesStack {
public static void Main() {
// Creates and initializes a new Stack.
Stack myStack = new Stack();
myStack.Push("Hello");
myStack.Push("World");
myStack.Push("!");
// Displays the properties and values of the Stack.
Console.WriteLine( "myStack" );
Console.WriteLine( "\tCount: {0}", myStack.Count );
Console.Write( "\tValues:" );
PrintValues( myStack );
}
public static void PrintValues( IEnumerable myCollection ) {
foreach ( Object obj in myCollection )
Console.Write( " {0}", obj );
Console.WriteLine();
}
}
/*
This code produces the following output.
myStack
Count: 3
Values: ! World Hello
*/
์ค๋ช
์ฉ๋์ Stack ๋ณด์ ํ ์ ์๋ Stack ์์์ ์์ ๋๋ค. ์์๊ฐ ์ถ๊ฐ Stack๋๋ฉด ์ฌํ ๋น์ ํตํด ํ์์ ๋ฐ๋ผ ์ฉ๋์ด ์๋์ผ๋ก ์ฆ๊ฐํฉ๋๋ค.
์ ๊ฐ๋ฐ์ ํด๋์ค๋ฅผ Stack ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค. ๋์ ์ ๋ค๋ฆญ System.Collections.Generic.Stack<T> ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์คํ Push ์ฉ๋๋ณด๋ค ์์ ๊ฒฝ์ฐ Count ์์ ์ ๋๋คO(1). ์ ์์๋ฅผ Push ์์ฉํ๊ธฐ ์ํด ์ฉ๋์ ๋๋ ค์ผ ํ๋ ๊ฒฝ์ฐ ์์ ์ด n Count๋ฉ๋๋คO(n). Pop ๋ ์์ ์ ๋๋ค O(1) .
Stack ๋ null ์ ํจํ ๊ฐ์ผ๋ก ํ์ฉ๋๊ณ ์ค๋ณต ์์๋ฅผ ํ์ฉํฉ๋๋ค.
์์ฑ์
Stack() | ๋น์ด ์๋ ์ํ์์ ๊ธฐ๋ณธ ์ด๊ธฐ ์ฉ๋์ ๊ฐ์ง๋ Stack ํด๋์ค์ ์ ์ธ์คํด์ค๋ฅผ ์ด๊ธฐํํฉ๋๋ค. |
Stack(ICollection) | ์ง์ ํ ์ปฌ๋ ์ ์์ ๋ณต์ฌ๋ ์์๊ฐ ํฌํจ๋์ด ์๊ณ ๋ณต์ฌ๋ ์์์ ์์ ๊ฐ์ ์ด๊ธฐ ์ฉ๋์ ๊ฐ์ง๋ Stack ํด๋์ค์ ์ ์ธ์คํด์ค๋ฅผ ์ด๊ธฐํํฉ๋๋ค. |
Stack(Int32) | ๋น์ด ์๋ ์ํ์ด๊ณ ์ง์ ํ ์ด๊ธฐ ์ฉ๋๊ณผ ๊ธฐ๋ณธ ์ด๊ธฐ ์ฉ๋ ์ค์์ ๋ ํฐ ์ฉ๋์ ๊ฐ์ง๋ Stack ํด๋์ค์ ์ ์ธ์คํด์ค๋ฅผ ์ด๊ธฐํํฉ๋๋ค. |
์์ฑ
Count | Stack์ ํฌํจ๋ ์์ ์๋ฅผ ๊ฐ์ ธ์ต๋๋ค. |
IsSynchronized | Stack์ ๋ํ ์ก์ธ์ค๊ฐ ๋๊ธฐํ๋์ด ์ค๋ ๋๋ก๋ถํฐ ์์ ํ๊ฒ ๋ณดํธ๋๋์ง๋ฅผ ๋ํ๋ด๋ ๊ฐ์ ๊ฐ์ ธ์ต๋๋ค. |
SyncRoot | Stack์ ๋ํ ์ก์ธ์ค๋ฅผ ๋๊ธฐํํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ต๋๋ค. |
๋ฉ์๋
Clear() | Stack์์ ๊ฐ์ฒด๋ฅผ ๋ชจ๋ ์ ๊ฑฐํฉ๋๋ค. |
Clone() | Stack์ ๋ถ๋ถ ๋ณต์ฌ๋ณธ์ ๋ง๋ญ๋๋ค. |
Contains(Object) | Stack์ ์์๊ฐ ์๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํฉ๋๋ค. |
CopyTo(Array, Int32) | ์ง์ ๋ ๋ฐฐ์ด ์ธ๋ฑ์ค์์ ์์ํ๋ ๊ธฐ์กด 1์ฐจ์ Array์ Stack๋ฅผ ๋ณต์ฌํฉ๋๋ค. |
Equals(Object) | ์ง์ ๋ ๊ฐ์ฒด๊ฐ ํ์ฌ ๊ฐ์ฒด์ ๊ฐ์์ง ํ์ธํฉ๋๋ค. (๋ค์์์ ์์๋จ Object) |
GetEnumerator() | IEnumerator์ Stack๋ฅผ ๋ฐํํฉ๋๋ค. |
GetHashCode() | ๊ธฐ๋ณธ ํด์ ํจ์๋ก ์๋ํฉ๋๋ค. (๋ค์์์ ์์๋จ Object) |
GetType() | ํ์ฌ ์ธ์คํด์ค์ Type์ ๊ฐ์ ธ์ต๋๋ค. (๋ค์์์ ์์๋จ Object) |
MemberwiseClone() | ํ์ฌ Object์ ๋จ์ ๋ณต์ฌ๋ณธ์ ๋ง๋ญ๋๋ค. (๋ค์์์ ์์๋จ Object) |
Peek() | Stack์ ๋งจ ์์์ ๊ฐ์ฒด๋ฅผ ์ ๊ฑฐํ์ง ์๊ณ ๋ฐํํฉ๋๋ค. |
Pop() | Stack์ ๋งจ ์์์ ๊ฐ์ฒด๋ฅผ ์ ๊ฑฐํ๊ณ ๋ฐํํฉ๋๋ค. |
Push(Object) | ๊ฐ์ฒด๋ฅผ Stack์ ๋งจ ์์ ์ฝ์ ํฉ๋๋ค. |
Synchronized(Stack) | ๋๊ธฐํ๋์ด ์ค๋ ๋๋ก๋ถํฐ ์์ ํ๊ฒ ๋ณดํธ๋๋ Stack์ ๋ํผ๋ฅผ ๋ฐํํฉ๋๋ค. |
ToArray() | Stack์ ์ ๋ฐฐ์ด์ ๋ณต์ฌํฉ๋๋ค. |
ToString() | ํ์ฌ ๊ฐ์ฒด๋ฅผ ๋ํ๋ด๋ ๋ฌธ์์ด์ ๋ฐํํฉ๋๋ค. (๋ค์์์ ์์๋จ Object) |
์ถ๊ฐ ์ ๋ณด
์์ stack ํด๋์ค๋ฅผ ํ์ ์คํฌ๋ฆฝํธ์ค๋ฝ๊ฒ ๊ฐ๋ตํํด์ ๊ตฌํํด๋ณด๋ ํฌ์คํ ์ด๋ค.
๋จ์ผ ์ฐ๊ฒฐ๋ฆฌ์คํธ ํ์ฉ
์์ดํ ๋ง๋ค ๋ ธ๋๊ฐ ํ๋์ฉ ์์ด, ๊ฐ์ ๋ค์ ๊ฒ์ ๊ฐ๋ฆฌํค๊ณ ์๋ค.
ํค๋(์ฒ์์ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ)๋ ์ฒซ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๊ณ ์๋ค.
<๋จ์ผ ์ฐ๊ฒฐ๋ฆฌ์คํธ๋ฅผ ์คํ ๊ตฌํ์ ์ ์ฉ>
์ฒ์์ ํค๋๊ฐ ์๋ฌด ๊ฒ๋ ๋ฐ๋ผ๋ณด์ง ์๊ณ ์ฒซ ๋ ธ๋๊ฐ ์๊ธฐ๋ฉด ์ฒซ ๋ ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ๋๋ค.
๋๋ฒ์งธ ๋ ธ๋๊ฐ ์๊ธฐ๋ฉด ๋๋ฒ์งธ ๋ ธ๋๋ ์ฒซ๋ฒ์งธ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ๋๋ค.
์ด์ ํค๋๋ ๋๋ฒ์งธ ๋ ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ๋ง๋ ๋ค.
์ฌ๊ธฐ์ pop()์ ํ๋ฉด ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋ ธ๋(๋๋ฒ์งธ ๋ ธ๋)๋ฅผ ์ฐพ์์,
๊ทธ ๋ ธ๋๊ฐ ๊ฐ๋ฆฌํค๊ณ ์๋ ์ด์ ์ ๋ ธ๋(์ฒซ๋ฒ์งธ ๋ ธ๋)๋ฅผ ํค๋๊ฐ ๋ฐ๋ผ๋ณด๋๋ก ๋ณ๊ฒฝํ๋ค.
๊ทธ๋ฌ๋ฉด ๋๋ฒ์งธ ๋ ธ๋๋ ๋ฌด์๋๋ค.
์ฌ๊ธฐ์ ๋ค์ pop()์ ํ๋ฉด
ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋ ธ๋(์ฒซ๋ฒ์งธ ๋ ธ๋)๋ฅผ ์ฐพ์์,
๊ทธ ๋ ธ๋๊ฐ ๊ฐ๋ฆฌํค๊ณ ์๋ ์ด์ ์ ๋ ธ๋๋ฅผ ํค๋๊ฐ ๋ฐ๋ผ๋ณด๋๋ก ๋ณ๊ฒฝํด์ผ ํ๋๋ฐ
์ฒซ๋ฒ์งธ ๋ ธ๋๊ฐ ๊ฐ๋ฆฌํค๊ณ ์๋ ์ด์ ๋ ธ๋๊ฐ ์์ผ๋ฏ๋ก,
ํค๋๊ฐ null์ ๋ฐ๋ผ๋ณด๋๋ก ๋ง๋ ๋ค.
์ด์ ํค๋๊ฐ null์ ๋ฐ๋ผ๋ณด๊ณ ์์ผ๋ฏ๋ก ์คํ์ ํ ํ ๋น์ด์๋ ์ํ๊ฐ ๋๋ค.
(๋๋ฒ์งธ ๋ ธ๋์ ์ฒซ๋ฒ์งธ ๋ ธ๋๊ฐ ์๊ธด ํ์ง๋ง ์ฐธ์กฐํ๊ณ ์๋ ๊ฒ๋ค์ด ์์ผ๋ฏ๋ก, ์์ฐ์ค๋ฝ๊ฒ ๋ฌด์๋๋ค.)
"๊ฐ์ธ ์๊ฐ : ํค๋๋ฅผ ํค๋์ท์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ ์ฌ์ด๋ฏ"
<์์ฑ ์ฝ๋>
interface Stack {
readonly size: number;
push(value: string): void;
pop(): string;
}
type StackNode = {
readonly value: string;
readonly next?: StackNode;
};
class StackImpl implements Stack {
private _size: number = 0;
//head๋ StackNode๋ฅผ ๋ฐ๋ผ๋ณผ ์๋, ์ ๋ฐ๋ผ๋ณด๊ณ ์์ ์๋ ์์(StackNode|undefined ๋ก ์ฐ๋ ๋์ , optional๋ก ์ง์ )
private head?: StackNode;
constructor(private capacity: number) {}
get size() {
return this._size;
}
push(value: string): void {
if (this.size === this.capacity) {
throw new Error("Stack is Full!!");
}
//node๋ StackNode(์ฌ์ฉ์ ์ง์ ๋
ธ๋)๋ผ๋ ๋ฐ์ดํฐํ์
์ ๋ฐ๋ผ๊ฐ๋ ๋
ธ๋๋ก,
//value๋ผ๋ ํค์ ์ ๋ฌ๋ฐ์ value๋ฅผ ํ ๋น๋ฐ๋๋ฐ ์ด๋ฆ์ด ๋๊ฐ์์ ๊ตณ์ด value:value๋ผ๊ณ ์ธ ํ์์์ด value๋ผ๊ณ ๋ง ์์ฑ
//next๋ head๊ฐ ๊ธฐ์กด์ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๊ฒ์ ๊ฐ๋ฆฌํค๋ฉด ๋จ!!!
const node: StackNode = { value, next: this.head };
//node๋ ์๋ก ๋ค์ด์จ ์์ด์ด๊ณ , head๋ ๋ค์ ์๋ก๋ค์ด์จ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ํ๋ค.
this.head = node;
this._size++;
}
pop(): string {
if (this.head == null) {
throw new Error("Stack is empty!");
}
const node = this.head;
this.head = node.next;
this._size--;
return node.value;
}
}
const stack = new StackImpl(10);
console.log(stack);
stack.push("๋ก๋ณถ์ด");
console.log(stack);
stack.push("์๋");
console.log(stack);
stack.push("ํผ์");
console.log(stack);
stack.push("๋ผ๋ฉด");
console.log(stack);
console.log(stack.pop());
console.log(stack);
console.log("์คํ์ ๋น์๋ด
์๋ค!");
while (stack.size != 0) {
console.log(stack.pop());
}
console.log(stack.pop());
<์ถ๋ ฅ ๊ฒฐ๊ณผ>
StackImpl { capacity: 10, _size: 0 }
StackImpl {
capacity: 10,
_size: 1,
head: { value: '๋ก๋ณถ์ด', next: undefined }
}
StackImpl {
capacity: 10,
_size: 2,
head: { value: '์๋', next: { value: '๋ก๋ณถ์ด', next: undefined } }
}
StackImpl {
capacity: 10,
_size: 3,
head: { value: 'ํผ์', next: { value: '์๋', next: [Object] } }
}
StackImpl {
capacity: 10,
_size: 4,
head: { value: '๋ผ๋ฉด', next: { value: 'ํผ์', next: [Object] } }
}
๋ผ๋ฉด
StackImpl {
capacity: 10,
_size: 3,
head: { value: 'ํผ์', next: { value: '์๋', next: [Object] } }
}
์คํ์ ๋น์๋ด
์๋ค!
ํผ์
์๋
๋ก๋ณถ์ด
/Users/์ ์ ์ด๋ฆ/Desktop/ํ์ ์ด๋ฆ/dist/index.js:29
throw new Error("Stack is empty!");
^
Error: Stack is empty!
<์ฝ๋ ํ์ >
1. ๋ฉค๋ฒ๋ณ์ size๋ ๋ ธ๋์ ๊ฐ์์ด๋ฏ๋ก, readonlyํ๊ฒ
๋ฉค๋ฒ ๋ณ์ size๊ฐ ์ฝ๊ธฐ ์ ์ฉ์ด๋๊น, ์ ๊ทผ์ ํ์ง์ ์ private๋ก ๋ด๋ถ์์๋ง ์ ๊ทผ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๊ณ
๋ด๋ถ ๋ณ์๋ผ๋ ๋ป์ผ๋ก _size๋ก ์์ฑํ ๋ค์,
getter ์ด์ฉํด์ ์ธ๋ถ์์ ์ ๊ทผ๊ฐ๋ฅ๋ง ๊ฐ๋ฅํ๊ฒ ์ด์ด์ค๋ค.
(setter๊ฐ ์์ผ๋๊น ์ค๋ก์ง ์ฝ๊ธฐ๋ง ๊ฐ๋ฅ!)
interface Stack {
readonly size: number;
push(value: string): void;
pop(): string;
}
class StackImpl implements Stack {
private _size: number = 0;
get size() {
return this._size;
}
2. pushํ๋ฉด _size++, popํ๋ฉด _size--;
interface Stack {
readonly size: number;
push(value: string): void;
pop(): string;
}
class StackImpl implements Stack {
private _size: number = 0;
get size() {
return this._size;
}
push(value: string): void {
this._size++;
}
pop(): string {
this._size--;
}
}
3. ์์ดํ ์ ๊ฐ์ ๋ ธ๋๋ฅผ typeํ ๋ณธ๊ฒฉ์ ์ธ push, pop ๊ตฌํ
์ถ๊ฐ๋๋ ๊ฐ ์์ดํ ๋ค์ ๋ ธ๋๋ก ๊ฐ์ผ ๋ค, head๊ฐ ์ด ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ฐฉ์์ ์ทจํ๋๋ก ํ๋ค.
์์ดํ ์ ๊ฐ์ ๋ ธ๋๋ฅผ type์ผ๋ก ์ง์ ํด์ค๋ค.
๋ํ, ์ด๋ฌํ ๋ฐ์ดํฐ(์ฌ์ฉ์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์๊ณ , ๊ทธ๊ฒ์ ํ๋จ๊ณ ๊ฐ์ธ๋ ์ด๋ฌํ ๋ฐ์ดํฐ๋ฅ)๋ฅผ ์ ์ํ ๋, ๋ถ๋ณ์ฑ์ ์ ์งํ๋ ๊ฒ์ด ์ข๋ค.
์ ๋ฌ๋ ๊ฐ์ด ์๋ค๋ฉด ๋ด์ฉ๋ฌผ์ด ๋ณ๊ฒฝ๋์ง ์๋๋ก readonly ํค์๋๋ฅผ ๋ฌ์์ฃผ์.
type StackNode = {
readonly value: string;
readonly next?: StackNode;
};
4. ๋ณธ๊ฒฉ์ ์ธ push
์๋ก์ด ๊ฐ์ด ๋ค์ด์จ๋ค๋ฉด node๋ก ๊ฐ์ธ๊ณ , ์ด node๋ head๊ฐ ๊ธฐ์กด์ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋ ธ๋๋ฅผ ๊ฐ๋ฆฌํค๊ฒ ํ๋ค.(์๋ ๊ทธ๋ฆผ)
์ถ๊ฐ๋ก head๋ฅผ ์๋ก ๋ค์ด์จ node๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ํ๋ค. (๊ทธ๋ฌ๋ฉด head๊ฐ ๊ธฐ์กด์ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋ฐฉ์์ ํฌ์ธํฐ๋ ์๋ ํด์ ๋จ)
๋จผ์ , ์๋ก์ด value๊ฐ ๋ค์ด ์ค๋ฉด ์ด value๋ฅผ ๊ฐ์ธ๋ ๋ ธ๋๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
interface Stack {
readonly size: number;
push(value: string): void;
pop(): string;
}
type StackNode = {
readonly value: string;
readonly next?: StackNode;
};
class StackImpl implements Stack {
private _size: number = 0;
//head๋ StackNode๋ฅผ ๋ฐ๋ผ๋ณผ ์๋, ์ ๋ฐ๋ผ๋ณด๊ณ ์์ ์๋ ์์(StackNode|undefined ๋ก ์ฐ๋ ๋์ , optional๋ก ์ง์ )
private head?: StackNode;
get size() {
return this._size;
}
push(value: string): void {
//node๋ StackNode(์ฌ์ฉ์ ์ง์ ๋
ธ๋)๋ผ๋ ๋ฐ์ดํฐํ์
์ ๋ฐ๋ผ๊ฐ๋ ๋
ธ๋๋ก,
//value๋ผ๋ ํค์ ์ ๋ฌ๋ฐ์ value๋ฅผ ํ ๋น๋ฐ๋๋ฐ ์ด๋ฆ์ด ๋๊ฐ์์ ๊ตณ์ด value:value๋ผ๊ณ ์ธ ํ์์์ด value๋ผ๊ณ ๋ง ์์ฑ
//next๋ head๊ฐ ๊ธฐ์กด์ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๊ฒ์ ๊ฐ๋ฆฌํค๋ฉด ๋จ!!!
const node: StackNode = { value, next: this.head };
//node๋ ์๋ก ๋ค์ด์จ ์์ด์ด๊ณ , head๋ ๋ค์ ์๋ก๋ค์ด์จ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ํ๋ค.
this.head = node;
this._size++;
}
4. ๋ณธ๊ฒฉ์ ์ธ pop ๊ตฌํ
- pop์ head๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋ ธ๋์ ๊ฐ๋ง ๋ฐํํ๊ณ ์ฐ๊ฒฐ ํด์ง๋๊ฒ๋
(head๋ ๋ค์ ์ด์ ๋ ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ํจ์ผ๋ก์จ ๊ฐ๋ฅ)
pop(): string {
//ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋
ธ๋์ value๋ฅผ ๋ฆฌํดํด์ฃผ๊ธฐ ์ํ ๊ธฐ์ด์์
(1)
const node = this.head;
//head๊ฐ ๋ค์ ์ด์ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ง์ (์ฌ์ค์ ์ฌ๊ธฐ์ ์ฐ๊ฒฐ๋๊น)
this.head = node.next;
//์คํ ์ฌ์ด์ฆ ์ค์ฌ์ฃผ๊ธฐ
this._size--;
//ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋
ธ๋์ value๋ฅผ ๋ฆฌํด(pop๋๊ณ ์ด์ ์ฌ์ค์ ๋ฌด์๋จ)
return node.value;
}
}
- ์คํ์ ์๋ฌด ๊ฒ๋ ์์ ๋ pop์ ํ๋ ๊ฒฝ์ฐ๋ ์๋ฌ ๋์ ธ์ฃผ๊ธฐ
pop(): string {
//์คํ์ด ๋น์ด์๋ ๊ฒฝ์ฐ์ node๊ฐ ์์ ์๋ ์๋ค.
//๊ทธ๋ฌ๋ API ์์ฒด์์ string | undefined๋ฅผ ํด์ฃผ๋ฉด ๋ค์ด๊ฐ ๋ ๋ง๋ค null check๋ฅผ ํ๊ฒ๋์ ๋ณ๋ก๊ณ ,(๊ฐ์ด ์๋์ง ์๋์ง ๋งค๋ฒ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํ๋ ๊ผด)
//ํญ์ ์๊ณ , ๋ฆฌํดํ ์ค๋น๊ฐ ๋์ด์๋ค๊ณ ์ง์ ํ๋ ๋์ ์ ์๋ if๋ฌธ ์์ฑ
// null == undefined, null !== undefined
if (this.head == null) {
throw new Error("Stack is empty!");
}
//ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋
ธ๋์ value๋ฅผ ๋ฆฌํดํด์ฃผ๊ธฐ ์ํ ๊ธฐ์ด์์
(1)
const node = this.head;
//head๊ฐ ๋ค์ ์ด์ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ง์ (์ฌ์ค์ ์ฌ๊ธฐ์ ์ฐ๊ฒฐ๋๊น)
this.head = node.next;
//์คํ ์ฌ์ด์ฆ ์ค์ฌ์ฃผ๊ธฐ
this._size--;
//ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋
ธ๋์ value๋ฅผ ๋ฆฌํด(pop๋๊ณ ์ด์ ์ฌ์ค์ ๋ฌด์๋จ)
return node.value;
}
5. ์์ฑํ ๋ size ๋ฒ์๋ฅผ ์ ํด์ฃผ๊ณ ์ถ๋ค๋ฉด...
๋ณดํต์ constructor์์ ์ผ๋ง๋งํผ์ ์ฉ๋(์คํ์ ์ฌ์ด์ฆ)์ผ๋ก ํ ๊ฑด์ง ์ธ์๋ก ์ ๋ฌ๋ฐ์ ์ ์๊ฒ๋ ๋ง๋ ๋ค.
constructor(private capacity: number) {}
์ด ์ ํด์ง ์ฌ์ด์ฆ ๋ด์์ ์ฌ์ฉํ ์ ์๊ฒ push ํจ์์ ๋ก์ง์ ์ถ๊ฐํ๋ค.
push(value: string): void {
//์ง๊ธ ์ฌ์ด์ฆ๊ฐ ์ ํด์ง ์ฉ๋๊ณผ ๋๊ฐ๋ค๋ฉด(๊ฝ ์ฐฌ ์ํ๋ผ๋ฉด ใ
ใ
)
if (this.size === this.capacity) {
throw new Error("Stack is Full!!");
}
//node๋ StackNode(์ฌ์ฉ์ ์ง์ ๋
ธ๋)๋ผ๋ ๋ฐ์ดํฐํ์
์ ๋ฐ๋ผ๊ฐ๋ ๋
ธ๋๋ก,
//value๋ผ๋ ํค์ ์ ๋ฌ๋ฐ์ value๋ฅผ ํ ๋น๋ฐ๋๋ฐ ์ด๋ฆ์ด ๋๊ฐ์์ ๊ตณ์ด value:value๋ผ๊ณ ์ธ ํ์์์ด value๋ผ๊ณ ๋ง ์์ฑ
//next๋ head๊ฐ ๊ธฐ์กด์ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๊ฒ์ ๊ฐ๋ฆฌํค๋ฉด ๋จ!!!
const node: StackNode = { value, next: this.head };
//node๋ ์๋ก ๋ค์ด์จ ์์ด์ด๊ณ , head๋ ๋ค์ ์๋ก๋ค์ด์จ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ํ๋ค.
this.head = node;
this._size++;
}
6. ์ต์ข ์ฝ๋
interface Stack {
readonly size: number;
push(value: string): void;
pop(): string;
}
type StackNode = {
readonly value: string;
readonly next?: StackNode;
};
class StackImpl implements Stack {
private _size: number = 0;
//head๋ StackNode๋ฅผ ๋ฐ๋ผ๋ณผ ์๋, ์ ๋ฐ๋ผ๋ณด๊ณ ์์ ์๋ ์์(StackNode|undefined ๋ก ์ฐ๋ ๋์ , optional๋ก ์ง์ )
private head?: StackNode;
constructor(private capacity: number) {}
get size() {
return this._size;
}
push(value: string): void {
//์ง๊ธ ์ฌ์ด์ฆ๊ฐ ์ ํด์ง ์ฉ๋๊ณผ ๋๊ฐ๋ค๋ฉด(๊ฝ ์ฐฌ ์ํ๋ผ๋ฉด ใ
ใ
)
if (this.size === this.capacity) {
throw new Error("Stack is Full!!");
}
//node๋ StackNode(์ฌ์ฉ์ ์ง์ ๋
ธ๋)๋ผ๋ ๋ฐ์ดํฐํ์
์ ๋ฐ๋ผ๊ฐ๋ ๋
ธ๋๋ก,
//value๋ผ๋ ํค์ ์ ๋ฌ๋ฐ์ value๋ฅผ ํ ๋น๋ฐ๋๋ฐ ์ด๋ฆ์ด ๋๊ฐ์์ ๊ตณ์ด value:value๋ผ๊ณ ์ธ ํ์์์ด value๋ผ๊ณ ๋ง ์์ฑ
//next๋ head๊ฐ ๊ธฐ์กด์ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๊ฒ์ ๊ฐ๋ฆฌํค๋ฉด ๋จ!!!
const node: StackNode = { value, next: this.head };
//node๋ ์๋ก ๋ค์ด์จ ์์ด์ด๊ณ , head๋ ๋ค์ ์๋ก๋ค์ด์จ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ํ๋ค.
this.head = node;
this._size++;
}
pop(): string {
//์คํ์ด ๋น์ด์๋ ๊ฒฝ์ฐ์ node๊ฐ ์์ ์๋ ์๋ค.
//๊ทธ๋ฌ๋ API ์์ฒด์์ string | undefined๋ฅผ ํด์ฃผ๋ฉด ๋ค์ด๊ฐ ๋ ๋ง๋ค null check๋ฅผ ํ๊ฒ๋์ ๋ณ๋ก๊ณ ,(๊ฐ์ด ์๋์ง ์๋์ง ๋งค๋ฒ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํ๋ ๊ผด)
//ํญ์ ์๊ณ , ๋ฆฌํดํ ์ค๋น๊ฐ ๋์ด์๋ค๊ณ ์ง์ ํ๋ ๋์ ์ ์๋ if๋ฌธ ์์ฑ
// null == undefined, null !== undefined
if (this.head == null) {
throw new Error("Stack is empty!");
}
//ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋
ธ๋์ value๋ฅผ ๋ฆฌํดํด์ฃผ๊ธฐ ์ํ ๊ธฐ์ด์์
(1)
const node = this.head;
//head๊ฐ ๋ค์ ์ด์ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ง์ (์ฌ์ค์ ์ฌ๊ธฐ์ ์ฐ๊ฒฐ๋๊น)
this.head = node.next;
//์คํ ์ฌ์ด์ฆ ์ค์ฌ์ฃผ๊ธฐ
this._size--;
//ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋
ธ๋์ value๋ฅผ ๋ฆฌํด(pop๋๊ณ ์ด์ ์ฌ์ค์ ๋ฌด์๋จ)
return node.value;
}
}
const stack = new StackImpl(10);
console.log(stack);
stack.push("๋ก๋ณถ์ด");
console.log(stack);
stack.push("์๋");
console.log(stack);
stack.push("ํผ์");
console.log(stack);
stack.push("๋ผ๋ฉด");
console.log(stack);
console.log(stack.pop());
console.log(stack);
console.log("์คํ์ ๋น์๋ด
์๋ค!");
while (stack.size != 0) {
console.log(stack.pop());
}
console.log(stack.pop());
์ถ๋ ฅ๊ฒฐ๊ณผ
StackImpl { capacity: 10, _size: 0 }
StackImpl {
capacity: 10,
_size: 1,
head: { value: '๋ก๋ณถ์ด', next: undefined }
}
StackImpl {
capacity: 10,
_size: 2,
head: { value: '์๋', next: { value: '๋ก๋ณถ์ด', next: undefined } }
}
StackImpl {
capacity: 10,
_size: 3,
head: { value: 'ํผ์', next: { value: '์๋', next: [Object] } }
}
StackImpl {
capacity: 10,
_size: 4,
head: { value: '๋ผ๋ฉด', next: { value: 'ํผ์', next: [Object] } }
}
๋ผ๋ฉด
StackImpl {
capacity: 10,
_size: 3,
head: { value: 'ํผ์', next: { value: '์๋', next: [Object] } }
}
์คํ์ ๋น์๋ด
์๋ค!
ํผ์
์๋
๋ก๋ณถ์ด
/Users/007/Desktop/tr/dist/index.js:34
throw new Error("Stack is empty!");
^
Error: Stack is empty!
7. ์คํ ์ฉ๋์ ์ ํํ๊ณ ์ถ์ง ์๋ค๋ฉด
interface Stack {
readonly size: number;
push(value: string): void;
pop(): string;
}
type StackNode = {
readonly value: string;
readonly next?: StackNode;
};
class StackImpl implements Stack {
private _size: number = 0;
//head๋ StackNode๋ฅผ ๋ฐ๋ผ๋ณผ ์๋, ์ ๋ฐ๋ผ๋ณด๊ณ ์์ ์๋ ์์(StackNode|undefined ๋ก ์ฐ๋ ๋์ , optional๋ก ์ง์ )
private head?: StackNode;
constructor(private capacity?: number) {}
get size() {
return this._size;
}
push(value: string): void {
//์ง๊ธ ์ฌ์ด์ฆ๊ฐ ์ ํด์ง ์ฉ๋๊ณผ ๋๊ฐ๋ค๋ฉด(๊ฝ ์ฐฌ ์ํ๋ผ๋ฉด ใ
ใ
)
if (this.capacity !== undefined) {
if (this.size === this.capacity) {
throw new Error("Stack is Full!!");
}
}
//node๋ StackNode(์ฌ์ฉ์ ์ง์ ๋
ธ๋)๋ผ๋ ๋ฐ์ดํฐํ์
์ ๋ฐ๋ผ๊ฐ๋ ๋
ธ๋๋ก,
//value๋ผ๋ ํค์ ์ ๋ฌ๋ฐ์ value๋ฅผ ํ ๋น๋ฐ๋๋ฐ ์ด๋ฆ์ด ๋๊ฐ์์ ๊ตณ์ด value:value๋ผ๊ณ ์ธ ํ์์์ด value๋ผ๊ณ ๋ง ์์ฑ
//next๋ head๊ฐ ๊ธฐ์กด์ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๊ฒ์ ๊ฐ๋ฆฌํค๋ฉด ๋จ!!!
const node: StackNode = { value, next: this.head };
//node๋ ์๋ก ๋ค์ด์จ ์์ด์ด๊ณ , head๋ ๋ค์ ์๋ก๋ค์ด์จ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ํ๋ค.
this.head = node;
this._size++;
}
pop(): string {
//์คํ์ด ๋น์ด์๋ ๊ฒฝ์ฐ์ node๊ฐ ์์ ์๋ ์๋ค.
//๊ทธ๋ฌ๋ API ์์ฒด์์ string | undefined๋ฅผ ํด์ฃผ๋ฉด ๋ค์ด๊ฐ ๋ ๋ง๋ค null check๋ฅผ ํ๊ฒ๋์ ๋ณ๋ก๊ณ ,(๊ฐ์ด ์๋์ง ์๋์ง ๋งค๋ฒ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํ๋ ๊ผด)
//ํญ์ ์๊ณ , ๋ฆฌํดํ ์ค๋น๊ฐ ๋์ด์๋ค๊ณ ์ง์ ํ๋ ๋์ ์ ์๋ if๋ฌธ ์์ฑ
// null == undefined, null !== undefined
if (this.head == null) {
throw new Error("Stack is empty!");
}
//ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋
ธ๋์ value๋ฅผ ๋ฆฌํดํด์ฃผ๊ธฐ ์ํ ๊ธฐ์ด์์
(1)
const node = this.head;
//head๊ฐ ๋ค์ ์ด์ ๋
ธ๋๋ฅผ ๋ฐ๋ผ๋ณด๋๋ก ์ง์ (์ฌ์ค์ ์ฌ๊ธฐ์ ์ฐ๊ฒฐ๋๊น)
this.head = node.next;
//์คํ ์ฌ์ด์ฆ ์ค์ฌ์ฃผ๊ธฐ
this._size--;
//ํค๋๊ฐ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋
ธ๋์ value๋ฅผ ๋ฆฌํด(pop๋๊ณ ์ด์ ์ฌ์ค์ ๋ฌด์๋จ)
return node.value;
}
}
const stack = new StackImpl();
console.log(stack);
stack.push("๋ก๋ณถ์ด");
console.log(stack);
stack.push("์๋");
console.log(stack);
stack.push("ํผ์");
console.log(stack);
stack.push("๋ผ๋ฉด");
console.log(stack);
console.log(stack.pop());
console.log(stack);
console.log("์คํ์ ๋น์๋ด
์๋ค!");
while (stack.size != 0) {
console.log(stack.pop());
}
console.log(stack.pop());
<์ถ๋ ฅ ๊ฒฐ๊ณผ>
StackImpl { capacity: undefined, _size: 0 }
StackImpl {
capacity: undefined,
_size: 1,
head: { value: '๋ก๋ณถ์ด', next: undefined }
}
StackImpl {
capacity: undefined,
_size: 2,
head: { value: '์๋', next: { value: '๋ก๋ณถ์ด', next: undefined } }
}
StackImpl {
capacity: undefined,
_size: 3,
head: { value: 'ํผ์', next: { value: '์๋', next: [Object] } }
}
StackImpl {
capacity: undefined,
_size: 4,
head: { value: '๋ผ๋ฉด', next: { value: 'ํผ์', next: [Object] } }
}
๋ผ๋ฉด
StackImpl {
capacity: undefined,
_size: 3,
head: { value: 'ํผ์', next: { value: '์๋', next: [Object] } }
}
์คํ์ ๋น์๋ด
์๋ค!
ํผ์
์๋
๋ก๋ณถ์ด
/Users/007/Desktop/tr/dist/index.js:36
throw new Error("Stack is empty!");
^
Error: Stack is empty!