TypeScript/ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ TypeScript

[ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ] ๊ฐ์ฒด์ง€ํ–ฅ์ ์œผ๋กœ Generic Stack<T> ํด๋ž˜์Šค ๊ตฌํ˜„ํ•˜๊ธฐ

Rainbow๐ŸŒˆCoder 2022. 4. 25. 17:56
728x90

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ฝƒ, ๊ฐ์ฒด์ง€ํ–ฅ์˜ ๊ฝƒ ์ œ๋„ค๋ฆญ

์ œ๋„ค๋ฆญ์€ ์–ด๋”œ ๊ฐ€๋„ ํ†ต์ƒ์ ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.(์žฌ์‚ฌ์šฉ์„ฑ์ด ๊ต‰์žฅํžˆ ๋†’๊ธฐ ๋•Œ๋ฌธ)

์ด์ „ํฌ์ŠคํŒ… stack์˜ ๋‹จ์ ์€ ์˜ค๋กœ์ง€ stringํ˜•๋งŒ push, pop ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋‹ค์–‘ํ•œ ํƒ€์ž…์„ push, pop ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ œ๋„ค๋ฆญ์„ ์ด์šฉํ•ด์„œ ํ™œ์šฉ์„ฑ๊ณผ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.

์œ ์—ฐํ•˜๊ณ  ํƒ€์ž…๋„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๊ณ , ์žฌ์‚ฌ์šฉ์„ ์ •๋ง ๋งŽ์ด ๋†’์ผ ์ˆ˜ ์žˆ๋Š” ์ œ๋„ค๋ฆญ์„ ๋งˆ์Šคํ„ฐํ•ด๋ณธ๋‹ค.

(์˜คํ”ˆ์†Œ์Šค๋‚˜ API ๋ฌธ์„œ๋ฅผ ๋ณผ ๋•Œ ์ œ๋„ค๋ฆญ์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ๋ง‰ํž˜์—†์ด ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.)

 

 

 

 

๊ฐ์ข… ์ œ๋„ค๋ฆญ ์ž๋ฃŒ๊ตฌ์กฐ๋“ค๋„ 'ํด๋ž˜์Šค'์ด๋‹ค.

๊ฐ€๋ น C#์˜ stack<T> ํด๋ž˜์Šค๋Š” ๋‹ค์Œ ๋งํฌ์™€ ๊ฐ™๋‹ค.

https://docs.microsoft.com/ko-kr/dotnet/api/system.collections.generic.stack-1?view=net-6.0 

 

Stack<T> ํด๋ž˜์Šค (System.Collections.Generic)

์ง€์ •ํ•œ ๋™์ผ ํ˜•์‹์˜ ์ธ์Šคํ„ด์Šค๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฐ€๋ณ€ ํฌ๊ธฐ LIFO(ํ›„์ž…์„ ์ถœ) ๋ฐฉ์‹์˜ ์ปฌ๋ ‰์…˜์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

docs.microsoft.com

์ •์˜

๋„ค์ž„์ŠคํŽ˜์ด์Šค:System.Collections.Generic์–ด์…ˆ๋ธ”๋ฆฌ:System.Collections.dll

์ง€์ •ํ•œ ๋™์ผ ํ˜•์‹์˜ ์ธ์Šคํ„ด์Šค๋กœ ์ด๋ฃจ์–ด์ง„ ๊ฐ€๋ณ€ ํฌ๊ธฐ LIFO(ํ›„์ž…์„ ์ถœ) ๋ฐฉ์‹์˜ ์ปฌ๋ ‰์…˜์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

C#๋ณต์‚ฌ
public class Stack<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.ICollection

ํ˜•์‹ ๋งค๊ฐœ ๋ณ€์ˆ˜

T

์Šคํƒ์— ์žˆ๋Š” ์š”์†Œ์˜ ํ˜•์‹์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ƒ์†

Stack<T>

๊ตฌํ˜„

์‹คํ–‰
using System;
using System.Collections.Generic;

class Example
{
    public static void Main()
    {
        Stack<string> numbers = new Stack<string>();
        numbers.Push("one");
        numbers.Push("two");
        numbers.Push("three");
        numbers.Push("four");
        numbers.Push("five");

        // A stack can be enumerated without disturbing its contents.
        foreach( string number in numbers )
        {
            Console.WriteLine(number);
        }

        Console.WriteLine("\nPopping '{0}'", numbers.Pop());
        Console.WriteLine("Peek at next item to destack: {0}",
            numbers.Peek());
        Console.WriteLine("Popping '{0}'", numbers.Pop());

        // Create a copy of the stack, using the ToArray method and the
        // constructor that accepts an IEnumerable<T>.
        Stack<string> stack2 = new Stack<string>(numbers.ToArray());

        Console.WriteLine("\nContents of the first copy:");
        foreach( string number in stack2 )
        {
            Console.WriteLine(number);
        }

        // Create an array twice the size of the stack and copy the
        // elements of the stack, starting at the middle of the
        // array.
        string[] array2 = new string[numbers.Count * 2];
        numbers.CopyTo(array2, numbers.Count);

        // Create a second stack, using the constructor that accepts an
        // IEnumerable(Of T).
        Stack<string> stack3 = new Stack<string>(array2);

        Console.WriteLine("\nContents of the second copy, with duplicates and nulls:");
        foreach( string number in stack3 )
        {
            Console.WriteLine(number);
        }

        Console.WriteLine("\nstack2.Contains(\"four\") = {0}",
            stack2.Contains("four"));

        Console.WriteLine("\nstack2.Clear()");
        stack2.Clear();
        Console.WriteLine("\nstack2.Count = {0}", stack2.Count);
    }
}

/* This code example produces the following output:

five
four
three
two
one

Popping 'five'
Peek at next item to destack: four
Popping 'four'

Contents of the first copy:
one
two
three

Contents of the second copy, with duplicates and nulls:
one
two
three




stack2.Contains("four") = False

stack2.Clear()

stack2.Count = 0
 */

 

 

1. C# ์ฒ˜๋Ÿผ ๋ชจ๋“  ํƒ€์ž… ๋ช…์‹œํ•ด์ฃผ๋ฉด์„œ ์ž‘์„ฑํ•ด๋ณด๊ธฐ

string


interface Stack<T> {
  readonly size: number;
  push(value: T): void;
  pop(): T;
}

type StackNode<T> = {
  readonly value: T;
  readonly next?: StackNode<T>;
};

class StackImpl<T> implements Stack<T> {
  private _size: number = 0;
  //head๋Š” StackNode๋ฅผ ๋ฐ”๋ผ๋ณผ ์ˆ˜๋„, ์•ˆ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ์„ ์ˆ˜๋„ ์žˆ์Œ(StackNode|undefined ๋กœ ์“ฐ๋Š” ๋Œ€์‹ , optional๋กœ ์ง€์ •)
  private head?: StackNode<T>;

  constructor(private capacity?: number) {}

  get size() {
    return this._size;
  }

  push(value: T): 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<T> = { value, next: this.head };
    //node๋Š” ์ƒˆ๋กœ ๋“ค์–ด์˜จ ์•„์ด์ด๊ณ , head๋Š” ๋‹ค์‹œ ์ƒˆ๋กœ๋“ค์–ด์˜จ ๋…ธ๋“œ๋ฅผ ๋ฐ”๋ผ๋ณด๊ฒŒ ํ•œ๋‹ค.
    this.head = node;
    this._size++;
  }
  pop(): T {
    //์Šคํƒ์ด ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ์— 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: StackImpl<string> = new StackImpl<string>();
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());

 

2. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๊ฐ์„ฑ์œผ๋กœ ํƒ€์ž… ์ฃผ์„๋งŒ ๋‹ฌ๊ธฐ

object

interface Stack<T> {
  readonly size: number;
  push(value: T): void;
  pop(): T;
}

type StackNode<T> = {
  readonly value: T;
  readonly next?: StackNode<T>;
};

class StackImpl<T> implements Stack<T> {
  private _size: number = 0;
  //head๋Š” StackNode๋ฅผ ๋ฐ”๋ผ๋ณผ ์ˆ˜๋„, ์•ˆ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ์„ ์ˆ˜๋„ ์žˆ์Œ(StackNode|undefined ๋กœ ์“ฐ๋Š” ๋Œ€์‹ , optional๋กœ ์ง€์ •)
  private head?: StackNode<T>;

  constructor(private capacity?: number) {}

  get size() {
    return this._size;
  }

  push(value: T): 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<T> = { value, next: this.head };
    //node๋Š” ์ƒˆ๋กœ ๋“ค์–ด์˜จ ์•„์ด์ด๊ณ , head๋Š” ๋‹ค์‹œ ์ƒˆ๋กœ๋“ค์–ด์˜จ ๋…ธ๋“œ๋ฅผ ๋ฐ”๋ผ๋ณด๊ฒŒ ํ•œ๋‹ค.
    this.head = node;
    this._size++;
  }
  pop(): T {
    //์Šคํƒ์ด ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ์— 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: StackImpl<object> = new StackImpl();
stack.push({ name: "์‹ ์งฑ๊ตฌ" });
console.log(stack);
stack.push({ name: "์‹ ์งฑ์•„" });
console.log(stack);
stack.push({ name: "ํฐ๋‘ฅ์ด" });
console.log(stack);
stack.push({ name: "์•ก์…˜๊ฐ€๋ฉด" });
console.log(stack);
console.log(stack.pop());

console.log(stack);

console.log("์Šคํƒ์„ ๋น„์›Œ๋ด…์‹œ๋‹ค!");
while (stack.size != 0) {
  console.log(stack.pop());
}
console.log(stack.pop());

 

 

 

3. ์ œ๋„ค๋ฆญ ํƒ€์ž…๋งŒ ํ•œ์ •ํ•ด์ฃผ๊ธฐ

boolean ํ˜• ํ…Œ์ŠคํŠธ


interface Stack<T> {
  readonly size: number;
  push(value: T): void;
  pop(): T;
}

type StackNode<T> = {
  readonly value: T;
  readonly next?: StackNode<T>;
};

class StackImpl<T> implements Stack<T> {
  private _size: number = 0;
  //head๋Š” StackNode๋ฅผ ๋ฐ”๋ผ๋ณผ ์ˆ˜๋„, ์•ˆ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ์„ ์ˆ˜๋„ ์žˆ์Œ(StackNode|undefined ๋กœ ์“ฐ๋Š” ๋Œ€์‹ , optional๋กœ ์ง€์ •)
  private head?: StackNode<T>;

  constructor(private capacity?: number) {}

  get size() {
    return this._size;
  }

  push(value: T): 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<T> = { value, next: this.head };
    //node๋Š” ์ƒˆ๋กœ ๋“ค์–ด์˜จ ์•„์ด์ด๊ณ , head๋Š” ๋‹ค์‹œ ์ƒˆ๋กœ๋“ค์–ด์˜จ ๋…ธ๋“œ๋ฅผ ๋ฐ”๋ผ๋ณด๊ฒŒ ํ•œ๋‹ค.
    this.head = node;
    this._size++;
  }
  pop(): T {
    //์Šคํƒ์ด ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ์— 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<boolean>();
stack.push(true);
console.log(stack);
stack.push(false);
console.log(stack);
stack.push(true);
console.log(stack);
stack.push(false);
console.log(stack);
console.log(stack.pop());

console.log(stack);

console.log("์Šคํƒ์„ ๋น„์›Œ๋ด…์‹œ๋‹ค!");
while (stack.size != 0) {
  console.log(stack.pop());
}
console.log(stack.pop());

 

4. ์ œ๋„ค๋ฆญ ํƒ€์ž…, ํƒ€์ž… ์ฃผ์„ ์ƒ๋žตํ•˜๊ณ  ์™„์ „ ์ถ”๋ก ์‹œํ‚ค๊ธฐ 

number๋กœ ํ…Œ์ŠคํŠธ

interface Stack<T> {
  readonly size: number;
  push(value: T): void;
  pop(): T;
}

type StackNode<T> = {
  readonly value: T;
  readonly next?: StackNode<T>;
};

class StackImpl<T> implements Stack<T> {
  private _size: number = 0;
  //head๋Š” StackNode๋ฅผ ๋ฐ”๋ผ๋ณผ ์ˆ˜๋„, ์•ˆ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ์„ ์ˆ˜๋„ ์žˆ์Œ(StackNode|undefined ๋กœ ์“ฐ๋Š” ๋Œ€์‹ , optional๋กœ ์ง€์ •)
  private head?: StackNode<T>;

  constructor(private capacity?: number) {}

  get size() {
    return this._size;
  }

  push(value: T): 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<T> = { value, next: this.head };
    //node๋Š” ์ƒˆ๋กœ ๋“ค์–ด์˜จ ์•„์ด์ด๊ณ , head๋Š” ๋‹ค์‹œ ์ƒˆ๋กœ๋“ค์–ด์˜จ ๋…ธ๋“œ๋ฅผ ๋ฐ”๋ผ๋ณด๊ฒŒ ํ•œ๋‹ค.
    this.head = node;
    this._size++;
  }
  pop(): T {
    //์Šคํƒ์ด ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ์— 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();
stack.push(1);
console.log(stack);
stack.push(2);
console.log(stack);
stack.push(3);
console.log(stack);
stack.push(4);
console.log(stack);
console.log(stack.pop());

console.log(stack);

console.log("์Šคํƒ์„ ๋น„์›Œ๋ด…์‹œ๋‹ค!");
while (stack.size != 0) {
  console.log(stack.pop());
}
console.log(stack.pop());

 

 

 

 

728x90