본문 바로가기

Swift Algorithms

Stack

Stack

stack은 쌓는다라는 의미로 마치 상자를 쌓듯이 자료를 쌓는 것을 의미합니다. 상자를 쌓게 되면 아래부터 상자를 못 빼듯이 처음 쌓인 순서대로 빠져나가는 것이 아닌 역순으로 뺄 수 있습니다. 이를 LIFO (Last - in - First - Out)이라 합니다. 

Push, Pop

Push - Stack의 맨 위에 데이터를 쌓습니다.

Pop - Stack 맨 위에서 테이터를 가져옵니다. 가져와서 삭제, 사용이 가능합니다.

struct Stack<Element> {

    private var storage : [Element] = []
    
    init() {}
    
    mutating func push(_ element : Element) {
        storage.append(element)
    }
    
    mutating func pop() -> Element? {
        return storage.popLast()
    }
}

extension Stack : CustomStringConvertible {
    
    var description: String {
        
        let topDivider = " -------top-------\n"
        let bottomDivider = "\n-------------"
        
        let stackElements = storage.map{ "\($0)"}.reversed().joined(separator: "\n")
        return topDivider + stackElements + bottomDivider
        
    }
}


var stack = Stack<Int>()
stack.push(20)
stack.push(10)
stack.push(3)
stack.push(99)

print("Before Popping")
print(stack)

print("After Popping")
stack.pop()
print(stack)
/*
Before Popping
 -------top-------
99
3
10
20
-------------
After Popping
 -------top-------
3
10
20
-------------*/

 

Stack 이라는 구조체를 만들고 storage라는 배열을 만듭니다.

push라는 메소드를 만들고 storage 배열에 append를 통해 아이템을 쌓는 동작을 구현합니다. 

pop이라는 메소드를 만들고 storage 배열에 popLast를 통해 마지막 아이템을 제거하고 값을 리턴하는 동작을 구현합니다.

CustomStringConvertible 프로토콜을 통해 Stack이 어떻게 구현되는지 시각화하기 위해 사용합니다. topDivider 상수를 통해 상단, bottomDivider상수를 통해 하단을 보여주는 문자열을 만듭니다. stackElements 상수에 storage를 문자열로 만들고 storage가 쌓는 것처럼 보여지기 위해. reversed와. joined를 이용해 배열의 아이템들을 한 개당 한 줄로 만듭니다. 모든 상수를 합칩니다.

stack 변수에 stack 인스턴스를 만든 후 원하는 값을 stack.push를 이용해 넣습니다. 그 후 pop을 할 경우와 비교하기 위해 Before Popping 과 After Popping을 나눈 뒤 비교합니다. 

*부가 사항

위 예제의 경우 처음부터 Stack을 쌓아야 합니다. 예를 들어 존재하는 배열에 Stack을 쌓으려면 어떻게 해야 할까? 

처음부터 아이템을 1개씩 넣기에는 코딩이 지저분해집니다.

struct Stack<Element> {

    private var storage : [Element] = []
    
    init(_ element : [Element]) {
        storage = element
    }
    
    mutating func push(_ element : Element) {
        storage.append(element)
    }
    
    mutating func pop() -> Element? {
        return storage.popLast()
    }
}

extension Stack : CustomStringConvertible {
    
    var description: String {
        
        let topDivider = " -------top-------\n"
        let bottomDivider = "\n-------------"
        
        let stackElements = storage.map{ "\($0)"}.reversed().joined(separator: "\n")
        return topDivider + stackElements + bottomDivider
        
    }
}

let array = [1.0, 2.0, 3.0, 4.0]
var setStack = Stack(array)
print(setStack)
/*
 -------top-------
4.0
3.0
2.0
1.0
-------------
*/

비어있던 init 생정자에 element 매개변수를 주고 storage = element를 넣습니다.

상수 array에 [1.0, 2.0, 3.0, 4.0]를 넣고 Stack의 매개변수에 array를 넣어줍니다. 

'Swift Algorithms' 카테고리의 다른 글

Queue  (0) 2020.07.11
Linked List  (0) 2020.07.06
Time Complexity  (0) 2020.07.06
7. Filter, Map, Reduce Higher Order Functions  (0) 2020.07.04
6. Fibonacci Sequence  (0) 2020.07.03