[Swift] 'Stack' Data Structure

dadahaeยท2022๋…„ 7์›” 17์ผ

Algorithm

๋ชฉ๋ก ๋ณด๊ธฐ
1/1
post-thumbnail

๐Ÿ“Œ swift๋กœ stack ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณด์ž!!!

0. Stack?

๋จผ์ € ๋“ค์–ด์˜จ๊ฒŒ ๋‚˜์ค‘์— ๋‚˜๊ฐ„๋‹ค. (First In, Last Out: FILO)
ํ˜น์€ ๋‚˜์ค‘์— ๋“ค์–ด์˜จ๊ฒŒ ๋จผ์ € ๋‚˜๊ฐ„๋‹ค! (Last In, First Out: LIFO)

๊ฐ€์žฅ ๋จผ์ € ๋“ค์–ด๊ฐ„ ์š”์†Œ๋Š” ๋ฐ‘์— ๊น”๋ ค์„œ ๊ฐ€์žฅ ๋‚˜์ค‘์— ๋‚˜์˜จ๋‹ค. ์ฑ…์„ ์ธต์ธต์ด ์Œ“์•„๋‘๋ฉด ์•„๋ž˜์ชฝ ์ฑ…์„ ๊บผ๋‚ด๋ ค๋ฉด ๊ฐ€์žฅ ์œ„์˜ ์ฑ…๋ถ€ํ„ฐ ๊บผ๋‚ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ•ด๋ณด์ž.

1. Stack์˜ ๊ตฌ์กฐ

์Šคํƒ ์ž๋ฃŒ๊ตฌ์กฐ๊ฐ€ ํ•˜๋Š” ์—ญํ• ์€ ๋งจ ๋’ค์— ์žˆ๋Š” ์š”์†Œ๋ฅผ ๋นผ๊ฑฐ๋‚˜(pop) ํ™•์ธํ•˜๊ณ (top), ์ƒˆ๋กœ์šด ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š”(push) ๊ฒƒ์ด๋‹ค. ์ด 3๊ฐ€์ง€ ๊ธฐ๋Šฅ์€ O(1)๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ ๊ฐ€์žฅ ํ•ต์‹ฌ ์—ญํ• ์ด๋‹ค. ์Šคํƒ์˜ ์ค‘๊ฐ„์— ์žˆ๋Š” ์š”์†Œ๋ฅผ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ๋ณดํ†ต ์Šคํƒ์„ โ€˜๋ฐฐ์—ด'๋กœ ๋งŒ๋“ค์–ด์„œ โ€˜๋ฐฐ์—ด'์˜ ๊ธฐ๋Šฅ์„ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ๊ฒƒ์ด์ง€ ์Šคํƒ ์ž์ฒด๊ฐ€ ๊ฐ€์ง€๋Š” ๊ธฐ๋Šฅ์€ ์•„๋‹ˆ๋‹น.

  • push

    • ์ƒˆ๋กœ์šด ์š”์†Œ๋ฅผ ๋งจ ๋์— ์ถ”๊ฐ€ํ•œ๋‹ค.

  • pop

    • ๋งจ ๋์˜ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

  • top (ํ‘์€ Peek)

    • ๋งจ ๋์˜ ์š”์†Œ๊ฐ€ ๋ญ”์ง€ ์•Œ๋ ค์ค€๋‹ค.

์Šคํƒ์„ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด ์ƒˆ๋กœ์šด ๊ฐ’์ด ๋“ค์–ด๊ฐˆ ์œ„์น˜, ์ฆ‰ ๋งˆ์ง€๋ง‰ ์š”์†Œ๊ฐ€ ์žˆ๋Š” ๊ณณ์„ ์•Œ์•„์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์•ผ ์ƒˆ๋กœ ๊ฐ’๋„ ์ถ”๊ฐ€ํ•˜๊ณ , ์ œ๊ฑฐ๋„ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ pos ๋ผ๋Š” ์ด๋ฆ„์˜ ๋ณ€์ˆ˜๋กœ ๊ตฌํ˜„ํ•˜์ž~

  • pos
    • ๋‹ค์Œ ์š”์†Œ๊ฐ€ ๋“ค์–ด๊ฐˆ ์ธ๋ฑ์Šค ์œ„์น˜ ๋ณ€์ˆ˜

2. ๊ตฌํ˜„

2.1 ์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ธฐ

๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์ฐพ์•„๋ดค๋Š”๋ฐ, ๋‹ค๋“ค struct๋กœ ๊ตฌํ˜„ํ•˜๋”๋ผ. ์ด์œ ๊ฐ€ ์žˆ๋Š”๊ฑด๊ฐ€? ๊ทธ๊ฑฐ์— ๋Œ€ํ•œ ๋‹ต์€ ์•„์ง ๋ชป์ฐพ์•˜๋‹ค. swift์—๋„ class ๊ฐ€ ์žˆ๋Š”๋ฐ ๋‹ค๋“ค struct๋ฅผ ์“ด๋‹ค. swift์—์„œ struct๋ฅผ ๋” ๋งŽ์ด ์“ด๋‹ค๋Š” ๊ฑด ์•Œ๊ณ  ์žˆ์—ˆ์ง€๋งŒ ์•„์ง๊นŒ์ง€ ์™œ์ธ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ๋‹ค. ์•„๋ฌดํŠผโ€ฆ

(1) ๊ธฐ๋ณธ ๊ตฌํ˜„

push, pop, top์„ pos ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋งŒ๋“ค์–ด๋ณด์ž. ์ด ๋ฐฉ๋ฒ•์€ ๋‹ค๋ฅธ ์–ธ์–ด์—๋„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค!

๐Ÿ”ดย ์ „์ฒด์ฝ”๋“œ

var max_size = 10005
var items = [String?](repeating: nil, count: max_size)
var pos: Int = 0

// push
func push(_ item: String) {
    items[pos] = item
    pos += 1
}

// pop
func pop() -> String? {
    pos -= 1
    return items[pos]
}

// top
func top() -> String? {
    return items[pos-1]
}

// --- ์‚ฌ์šฉ๋ฒ• ---
push("hi")
push("my")
push("name")
push("is")
push("swift.")

print(items)   // [Optional("hi"), Optional("my"), Optional("name"), Optional("is"), Optional("swift."), nil, ... , nil]

pop()          // Optional("swift.")
pop()          // Optional("is")

top()          // Optional("name")

๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•˜๊ณ  pos๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด์œผ๋กœ ์Šคํƒ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ์ด๊ฒŒ ์ข‹์€ ์ฝ”๋“œ๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ฌผ๋ก  ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”๊ฒŒ ํ‹€๋ฆฐ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ ๊ฐ๊ฐ์˜ ์–ธ์–ด์— ํŠน์„ฑ์— ๋งž๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”๊ฒŒ ๋” ์ข‹์ง€ ์•Š์„๊นŒ ํ•œ๋‹ค. python๋„, C++๋„ ์œ„์˜ ์ฝ”๋“œ ํ˜•์‹์œผ๋กœ ๋ชจ๋‘ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

swift์˜ ์–ธ์–ด์˜ ํŠน์ง•์— ๋งž๊ฒŒ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ธฐ๋ณธ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ์ถฉ๋ถ„ํžˆ ์Šคํƒ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ธฐ๋ณธ์ ์ธ ์Šคํƒ์˜ ์„ฑ์งˆ์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ์œ„์™€ ๊ฐ™์ด ๊ตฌํ˜„ํ•ด๋ณด์•˜๋‹ค.

ํ•„์š”ํ•˜๋‹ค๋ฉด pos ์—†์ด ์•„๋ž˜์˜ (2),(3) ์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

(2)๋ฒˆ๊ณผ (3)๋ฒˆ์˜ ๊ตฌํ˜„์€ ๋ชจ๋‘ ๊ตฌ์กฐ์ฒด ์•ˆ์— ๋ฉ”์†Œ๋“œ์™€ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ตฌ์กฐ์ฒด ์—†์ด ์œ„์ฒ˜๋Ÿผ ๋ฒ—๊ธฐ๊ณ  ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค!!
๋‘˜์˜ ์ฐจ์ด์ ์„ ์•Œ๊ณ  ์ ์ ˆํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

(2) ๋ฐฐ์—ด์˜ ๋งˆ์ง€๋ง‰์— ๊ฐ’์„ ๋„ฃ๊ณ , ์ œ๊ฑฐํ•˜๋Š” ๋ฐฉ๋ฒ• โœจ

๋ฐฐ์—ด์„ ์ด์šฉํ•˜์—ฌ ์Šคํƒ์„ ๊ตฌํ˜„ํ•œ๋‹ค. ์ด๋•Œ ์ƒˆ๋กœ์šด item์€ ๋ฐฐ์—ด์˜ ๋์— ์ถ”๊ฐ€ํ•˜๊ณ , ์‚ญ์ œํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” pos ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

โœ”๏ธย ๊ตฌ์กฐ์ฒด ์„ ์–ธ

struct Stack {
	var items: [String] = []
}

Stack ์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๊ตฌ์กฐ์ฒด(struct)๋ฅผ ์„ ์–ธํ•˜๊ณ , ๋‚ด๋ถ€์— ๋ฐฐ์—ด(array)์„ ํ”„๋กœํผํ‹ฐ(property)๋กœ ์ƒ์„ฑํ•œ๋‹ค. items๋ฅผ ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์—์„œ๋งŒ ์“ธ ์˜ˆ์ •์ด๋ผ๋ฉด private ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์ฃผ๋„๋ก ํ•˜์ž. ์šฉ๋„์— ๋งž๊ฒŒ ์ ์ ˆํ•œ ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์ฃผ์ž.

โœ”๏ธย push

// 1
mutating func push(_ item:String) {
	// 2
	self.items.append(item)
}
  1. ์ƒˆ๋กœ์šด item์„ ์Šคํƒ์— ์ถ”๊ฐ€ํ•˜๋Š” push ํ•จ์ˆ˜์ด๋‹ค. ์ด ํ•จ์ˆ˜๋Š” items ๋ฐฐ์—ด์˜ ๋งจ ๋’ค์— ์ƒˆ๋กœ์šด item์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

    • items์˜ ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•˜๋ฏ€๋กœ mutating ํ‚ค์›Œ๋“œ๋ฅผ ํ•จ์ˆ˜ ์„ ์–ธ๋ถ€์— ์ถ”๊ฐ€ํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด swift์˜ struct๋Š” ๊ฐ’(value) ํƒ€์ž…์ด๋ฏ€๋กœ struct์˜ ๋ณ€์ˆ˜ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ์—์„œ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฆ‰, push ํ•จ์ˆ˜๋Š” Stack struct์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์†Œ๋“œ์ด๊ณ , ์ด ํ•จ์ˆ˜์—์„œ๋Š” Stack struct์˜ ๋ณ€์ˆ˜ ํ”„๋กœํผํ‹ฐ items์˜ ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— mutating ํ‚ค์›Œ๋“œ๋ฅผ ํ•จ์ˆ˜ ์„ ์–ธ ์•ž์— ๋ถ™์—ฌ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

    ๐Ÿ’กย **mutating ํ‚ค์›Œ๋“œ**

    struct์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์ˆ˜(constant)๋กœ ์„ ์–ธํ•˜๋ฉด struct์˜ ๋ณ€์ˆ˜ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜๊ฐ€ ์—†๋‹ค. ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ƒ์ˆ˜๋“  ๋ณ€์ˆ˜๋“  ๋ญ๋ผ๊ณ  ์„ ์–ธ๋˜์—ˆ๋“ ์ง€ ๊ฐ„์— ๋ชจ๋‘ ๋‹ค ์ƒ์ˆ˜๋กœ ์ทจ๊ธ‰๋œ๋‹ค.

    let stk1 = Stack()  // ์ƒ์ˆ˜๋กœ ์„ ์–ธํ•œ Stack struct์˜ ์ธ์Šคํ„ด์Šค stk1์ด๋‹ค.
    var stk2 = Stack()  // ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•œ Stack struct์˜ ์ธ์Šคํ„ด์Šค stk2์ด๋‹ค.

    ๊ทธ๋Ÿฌ๋‚˜ ๋ฌธ์ œ๋Š” Swift์—์„œ struct๋ฅผ ๋งŒ๋“ค๋ฉด Swift๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ด struct๋ฅผ ๋ณ€์ˆ˜๋กœ ์“ธ์ง€ ์ƒ์ˆ˜๋กœ ์“ธ์ง€ ๋ชจ๋ฅธ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค(!). ์ƒ์ˆ˜๋กœ ์„ ์–ธ๋˜๋ฉด ์•„์˜ˆ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๋ณ€์ˆ˜๋กœ ์„ ์–ธ๋˜๋ฉด ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์•ˆ์ „ํ•œ ์ ‘๊ทผ์„ ์œ„ํ•ด ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ตฌ์ฒด์ ์œผ๋กœ ์š”์ฒญ(request)๋ฅผ ํ•ด์•ผ ํ•œ๋‹ค. โ€˜์ด ํ•จ์ˆ˜๋Š” ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด์ฃผ๋Š” ํ•จ์ˆ˜์—์š”'๋ผ๊ณ  ํ‘œ์‹œ๋ฅผ ํ•ด์ค€๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ํŽธํ•˜๋‹ค.

    ์—ฌ๊ธฐ์„œ ์š”์ฒญ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฉ”์†Œ๋“œ ์„ ์–ธ๋ถ€ ์•ž์— mutating ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

  2. ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ items์— ์ƒˆ๋กœ์šด item์„ append๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ถ”๊ฐ€ํ•œ๋‹ค. ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(1)์ด ๋œ๋‹ค.

โœ”๏ธย pop

mutating func pop() -> String? {
	return self.items.popLast()
}

items์˜ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ์žˆ๋Š” ์š”์†Œ๋ฅผ [popLast()](https://developer.apple.com/documentation/swift/array/poplast())๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๊ฑฐํ•œ๋‹ค. popํ•จ์ˆ˜๋„ ํ”„๋กœํผํ‹ฐ(items)์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฏ€๋กœ mutating ํ‚ค์›Œ๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(1)์ด๋‹ค.

โœ”๏ธย top

func top() -> String? {
	return self.items.last
}

top์€ ๋ฐฐ์—ด์˜ last๋กœ ๋งˆ์ง€๋ง‰ ์š”์†Œ๋ฅผ ๊ตฌํ•œ๋‹ค. ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(1)์ด๋‹ค.

๐Ÿ”ดย ์ „์ฒด ์ฝ”๋“œ

struct Stack {
    var items: [String] = []
    
    mutating func push(_ item:String) {
        self.items.append(item)
    }
    
    mutating func pop() -> String? {
        return self.items.popLast()
    }
    
    func top() -> String? {
        return self.items.last
    }
}

๐Ÿ”ตย ์‚ฌ์šฉ๋ฒ•

var stk = Stack()

stk.push("hi")     // Stack(items: ["hi"])
stk.push("my")     // Stack(items: ["hi", "my"])
stk.push("name")   // Stack(items: ["hi", "my", "name"])
stk.push("is")     // Stack(items: ["hi", "my", "name", "is"])
stk.push("swift.") // Stack(items: ["hi", "my", "name", "is", "swift."])

stk.pop()          // Optional("swift.")

stk.push("python.") // Stack(items: ["hi", "my", "name", "is", "python."])

stk.top()          // Optional("python.")

์•„์ฃผ ์ž˜ ์ž‘๋™ํ•œ๋‹ค. ๋‹จ์ง€ pop๊ณผ top์˜ ๊ฒฐ๊ณผ๊ฐ€ ์˜ต์…”๋„์ธ ์ด์œ ๋Š” ๋ฆฌํ„ด๊ฐ’์„ ์˜ต์…”๋„๋กœ ์ฒ˜๋ฆฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค(์™€~).

(3) ๋ฐฐ์—ด์˜ ์ฒ˜์Œ์— ๊ฐ’์„ ๋„ฃ๊ณ , ์ œ๊ฑฐํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ฐฐ์—ด์„ ์ด์šฉํ•œ ์Šคํƒ ๊ตฌํ˜„์„ ๋‹ค๋ฅด๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค. ๋Œ€์‹  ์‹œ๊ฐ„ ๋ณต์žก๋„์—์„œ ์ฐจ์ด๊ฐ€ ๋‚œ๋‹คโ—๏ธ

์ด๋ฒˆ์—” ๋ฐฐ์—ด์˜ ๊ฐ€์žฅ ์ฒซ๋ฒˆ์งธ์— ์ƒˆ๋กœ์šด ์š”์†Œ๋ฅผ ์ถ”๊ฐ€(push)ํ•˜๊ณ , ์‚ญ์ œ(pop)ํ•ด๋ณด๋„๋ก ํ•˜์ž.

โœ”๏ธย ๊ตฌ์กฐ์ฒด ์„ ์–ธ

struct Stack {
	var items: [String] = []
}

๋ฌธ์ž์—ด์„ ์ž๋ฃŒํ˜•์œผ๋กœ ํ•˜๋Š” ๋ฐฐ์—ด๊ณผ Stack ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

โœ”๏ธย push

mutating func push(_ item: String) {
	self.items.insert(item, at: 0)
}

๋ฐฐ์—ด์˜ insert(contentsof:at:)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 0๋ฒˆ์งธ ์ธ๋ฑ์Šค์— ๊ฐ’์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(n+m)์ด๋‹ค.

โœ”๏ธย pop

mutating func pop() -> String? {
	return self.items.removeFirst()
}

๋ฐฐ์—ด์˜ removefirst(_:)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ถ”๊ฐ€๋œ ๊ฐ’(์ธ๋ฑ์Šค 0์ธ ๊ฐ’)์„ ์ œ๊ฑฐํ•œ๋‹ค. ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(n)์ด๋‹ค.

โœ”๏ธย top

func top() -> String? {
	return self.items.first
}

๋ฐฐ์—ด์˜ first๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์žฅ ์ตœ๊ทผ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค. ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(1)์ด๋‹ค.

๐Ÿ”ดย ์ „์ฒด์ฝ”๋“œ

struct Stack {
    var items: [String] = []
    
    mutating func push(_ item: String) {
        self.items.insert(item, at: 0)
    }
    
    mutating func pop() -> String? {
        return self.items.removeFirst()
    }
    
    func top() -> String? {
        return self.items.first
    }
    
}

๐Ÿ”ตย ์‚ฌ์šฉ๋ฒ•

var stk = Stack()

stk.push("hi")       // Stack(items: ["hi"])
stk.push("my")       // Stack(items: ["my", "hi"])
stk.push("name")     // Stack(items: ["name", "my", "hi"])
stk.push("is")       // Stack(items: ["is", "name", "my", "hi"])
stk.push("swift.")   // Stack(items: ["swift.", "is", "name", "my", "hi"])

stk.pop()            // Optional("swift.")

stk.push("python.")  // Stack(items: ["python.", "is", "name", "my", "hi"])

stk.top()            // Optional("python.")

์ƒˆ๋กœ์šด item์€ items ๋ฐฐ์—ด์˜ ๊ฐ€์žฅ ์ฒซ๋ฒˆ์งธ ์ธ๋ฑ์Šค์— ๋“ค์–ด์˜จ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ pop์„ ํ•˜๋ฉด ๊ฐ€์žฅ ๋‚˜์ค‘์— ์ถ”๊ฐ€๋œ item์ด ์ œ๊ฑฐ๋œ๋‹ค.

2.2 ์ฝ”๋“œ๋ฅผ ์ง„ํ™”์‹œ์ผœ๋ณด์ž

์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•ด์„œ ์Šคํƒ์„ ๊ตฌํ˜„ํ–ˆ๋‹ค. ๊ทผ๋ฐ ์—ฌ๊ธฐ์„œ ์Šคํƒ ๊ตฌ์กฐ์ฒด๋ฅผ ๋” โ€˜์•„๋ฆ„๋‹ต๊ฒŒ' ๋ฐœ์ „ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  1. ์Šคํƒ ๊ตฌ์กฐ์ฒด๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ธฐ๋ณธ โ€˜ํ‹€'์„ ๋งŒ๋“ค ์ˆ˜๋Š” ์—†์„๊นŒ?
  2. String ํƒ€์ž… ๋ง๊ณ  ๋‹ค๋ฅธ ํƒ€์ž…๋„ ์Šคํƒ์— ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์—†์„๊นŒ?

โœ… CustomStringConvertible

๊ทธ๋ƒฅ ์Šคํƒ ๊ตฌ์กฐ์ฒด๋งŒ ์ถœ๋ ฅํ•˜๋ฉด ์–ด๋–ค ๊ฐ’์ด ์•ž์ด๊ณ  ๋’ค์ธ์ง€ ์•Œ๊ธฐ ์–ด๋ ต๋‹ค. swift์—์„œ ์ œ๊ณตํ•˜๋Š” CustomStringConvertible ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ํ˜•ํƒœ๋กœ ์ถœ๋ ฅ์„ ์ปค์Šคํ…€ํ•  ์ˆ˜ ์žˆ๋‹ค! ์™€์•„์•™

extension Stack: CustomStringConvertible {
		
    var description: String {
        let header = "----Stack----\n"
        let body = items.reversed().joined(separator: "\n")
        let footer = "\n-------------\n"
        return header+body+footer
    }

}

์ด๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉ๋œ๋‹ค!!

var stk = Stack()

stk.push("hi")     
stk.push("my")     
stk.push("name")  
stk.push("is")
stk.push("swift.")

print(stk)

/*
----Stack----
swift.
is
name
my
hi
-------------
*/

Stack์˜ ๋ชจ์–‘์„ ์•Œ๊ธฐ ์‰ฝ๊ฒŒ ์ถœ๋ ฅ์ด ๋œ๋‹ค. CustomStringConvertible ํ”„๋กœํ† ์ฝœ์€ ์„ ํƒ์‚ฌํ•ญ์ด๋ฏ€๋กœ ํ•„์š”์— ๋”ฐ๋ผ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

โœ…ย Generic Types

์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“  ์Šคํƒ์€ String ์ž๋ฃŒํ˜•์œผ๋กœ๋งŒ ์„ ์–ธํ–ˆ๋‹ค. ๊ทธ๋Ÿผ ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•์˜ ์Šคํƒ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋˜ ๋˜‘๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋‚˜? ๋„ˆ๋ฌด ๋น„ํšจ์œจ์ ์ธ๋ฐโ€ฆ

Swift๋Š” ์ด๋ฅผ ์œ„ํ•ด Generic Type์„ ์ œ๊ณตํ•œ๋‹ค. Genericํ•œ ์ฝ”๋“œ๋Š” ๋ชจ๋“  ์ž๋ฃŒํ˜•์„ ์ˆ˜์šฉํ•  ์ˆ˜ ์žˆ์–ด ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค~~

์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด๋ณผ ์ฝ”๋“œ๋Š” (2)์˜ ๊ตฌ์กฐ์ฒด์ด๋‹ค.

// 1
struct Stack<T> {
		// 2
    var items: [T] = []
    // 3
    mutating func push(_ T) {
        self.items.append(item)
    }
    
    mutating func pop() -> T? {
        return self.items.popLast()
    }
    
    func top() -> T? {
        return self.items.last
    }
}
  1. ๊ตฌ์กฐ์ฒด์˜ ์ด๋ฆ„ ์˜†์— ๊บฝ์‡ ๋กœ ์ž๋ฃŒํ˜•์ด ๋“ค์–ด๊ฐˆ ์ž๋ฆฌ์˜ ์ด๋ฆ„(placeholderย type name)์„ ์ ์–ด์ค€๋‹ค. ์ฟ ์ฟก.
  2. ๊ธฐ์กด์— String์ด ์“ฐ์˜€๋˜ ๋ถ€๋ถ„์„ placeholderย type name์œผ๋กœ ๋Œ€์ฒดํ•œ๋‹ค.
  3. ํ•จ์ˆ˜์—์„œ ์“ฐ๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋„ ๋ชจ๋‘ ์ ์šฉํ•ด์ค€๋‹ค.

์ด์ œ String ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ์ž๋ฃŒํ˜•์ด ์ด ์Šคํƒ ๊ตฌ์กฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

2.3 Swift Collections์˜ Deque

์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ๋‹ค๋ณด๋ฉด ๊ธฐ๋ณธ ๋‚ด์žฅ Stack์€ ์—†๋‚˜โ€ฆ ์ƒ๊ฐํ•  ๊ฒƒ์ด๋‹ค. C++์˜ STL์ด๋‚˜ Python์˜ Collections ์ฒ˜๋Ÿผ!

๊ทธ๋ž˜์„œ ์•Œ์•„๋ณด๋‹ˆ Swift๋„ ๊ธฐ๋ณธ ์Šคํƒ ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋”๋ผ!! ๋ฌผ๋ก  ์Šคํƒ ํ•˜๋‚˜๋กœ ์“ฐ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  deque๋กœ ์“ด๋‹ค. ์ด๊ฑธ๋กœ stack, queue, deque๊นŒ์ง€ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฆ„๋„ python์˜ collections.deque์™€ ๊ฐ™๋‹ค.

๊ต‰์žฅํžˆ ์ตœ๊ทผ์— ๋‚˜์˜จ ๊ฒƒ์œผ๋กœ ํ™•์ธ์ด ๋œ๋‹ค. (Swift Collections 1.0.2 released on 16 Nov 2021, apple swift-collections github)

Swift Collections
is an open-source package of data structure implementations for the Swift programming language.

Deque, a double-ended queue backed by a ring buffer. Deques are range-replaceable, mutable, random-access collections.

Deque์˜ ๋ฉ”์†Œ๋“œ์—๋Š” append, prepend, popFirst, popLast๊ฐ€ ์žˆ์œผ๋ฉฐ ํŠน์ • ์ธ๋ฑ์Šค์— ์‚ฝ์ž…๊ณผ ์‚ญ์ œ๋ฅผ ์œ„ํ•œ insert(item, at:), remove(at:)์ด ์žˆ๋‹ค.

๊ทธ๋Ÿผ swift collections์˜ deque๋ฅผ stack์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

๋‹จ, DequeModule์„ ์ž„ํฌํŠธ ํ•ด์ค˜์•ผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
xcode ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋‹ˆ Collections ํŒจํ‚ค์ง€๋ฅผ ๋‹ค์šด๋ฐ›์•„์ค˜์•ผ ํ–ˆ๋‹ค. ๊ผญ ํ™•์ธํ•  ๊ฒƒโ—๏ธ

์ฝ”๋“œ๋Š” ์• ํ”Œ ๊ณต์‹ ๊นƒํ—ˆ๋ธŒ๋ฅผ ์ฐธ๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค.

(1) push โ†’ append

var colors: Deque = ["red", "yellow", "blue"]

colors.append("green")  // ๋ฐฐ์—ด์˜ ๋’ค์— ์ถ”๊ฐ€
colors.prepend("black") // ๋ฐฐ์—ด์˜ ์•ž์— ์ถ”๊ฐ€

์Šคํƒ์˜ Push๋Š” append๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.

(2) pop โ†’ popLast

var colors: Deque = ["black", "red", "yellow", "blue", "green"]

colors.popLast()   // ๋ฐฐ์—ด์˜ ๋’ท ์š”์†Œ ์ œ๊ฑฐ
colors.popFirst()  // ๋ฐฐ์—ด์˜ ์•ž ์š”์†Œ ์ œ๊ฑฐ

์Šคํƒ์˜ pop์€ popLast๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ฒ ๋‹ค.

(3) top โ†’ last

Deque๋Š” Array์™€ ๋น„์Šทํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค๊ณ  ํ•˜๋‹ˆ, top์˜ ๊ธฐ๋Šฅ์€ ๊ธฐ์กด๊ณผ ๋™์ผํ•˜๊ฒŒ last๋ฅผ ์“ฐ๋ฉด ๋œ๋‹ค.

๐Ÿ“’ย ์ •๋ฆฌ

์ง€๊ธˆ๊นŒ์ง€ Swift์—์„œ Stack์˜ ๊ตฌํ˜„์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•ด๋ณด์•˜๋‹ค. C++๊ณผ Python์œผ๋กœ๋งŒ ํ•˜๋‹ฅ ์ฒ˜์Œ Swift๋กœ ํ•ด๋ดค๋Š”๋ฐ python์ด๋ž‘ ๋น„์Šท~~ํ•˜๋ฉด์„œ๋„ ์ž๋ฃŒํ˜• ์„ ์–ธ ๋•Œ๋ฌธ์— ์กฐ๊ธˆ ๊นŒํƒˆ์Šค๋Ÿฝ๊ธดํ–ˆ๋‹ค. ๊ทธ๋ž˜๋„ ์Šคํƒ์€ ์—ญ์‹œ ๊ฐ„๋‹จํ•˜๊ณ .. ์žฌ๋ฐŒ๋‹ค.

ํ•„์š”์— ๋”ฐ๋ผ Swift์—์„œ ์Šคํƒ์„ ๊ตฌํ˜„ํ•˜๋ฉด ๋˜๊ณ , ๊ตฌ์กฐ์ฒด๋กœ ๋งŒ๋“œ๋Š”๊ฒŒ ์–ด๋ ต์ง€ ์•Š์•„์„œ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ๋ฐฐ์—ด๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์ž! ๋งŒ์•ฝ ์ฝ”ํ…Œ์—์„œ Collections์˜ Deque๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜์ž. ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ์„ ์“ฐ๋Š”๊ฒŒ ๋””๋ฒ„๊น…ํ•  ๋•Œ ํŽธํ•˜๋‹ค!


reference

https://medium.com/devslopes-blog/swift-data-structures-stack-4f301e4fa0dc

https://nitinagam17.medium.com/data-structure-in-swift-stack-part-3-81fdb946b160

https://www.raywenderlich.com/800-swift-algorithm-club-swift-stack-data-structure

https://stackoverflow.com/questions/57059558/is-there-a-built-in-stack-implementation-in-swift

https://docs.swift.org/swift-book/LanguageGuide/Generics.html

https://github.com/apple/swift-collections

https://www.hackingwithswift.com/sixty/7/5/mutating-methods

https://hyerios.tistory.com/190

swift array ์„ ์–ธ์‹œ ํฌ๊ธฐ ์ดˆ๊ธฐํ™” : https://stackoverflow.com/questions/24395105/how-to-create-a-fixed-size-array-of-objects

profile
iOS / Swift

0๊ฐœ์˜ ๋Œ“๊ธ€