ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스택
    CS(ComputerScience) 2021. 5. 18. 09:38

    안녕하십니까. 그린입니다🟢

    이번 포스팅에서는 스택에 대해 알아보고 Swift로 구현해보겠습니다🧑🏻‍💻

     

    스택

    : 후입선출 자료구조 (LIFO)

     -> 기능이 제한된 배열 (푸쉬/팝/픽의 세가지 역할밖에 못함)

     -> 순서가 중요할때 가장 뒤 순서의 데이터를 꺼냄으로 배열 크기와 상관없이 항상 O(1)의 시간 복잡도를 가짐 (배열보다 효율적)

     -> 중간 데이터 삭제 불가능

    Swift로 스택 구현하기

    import Foundation
    
    struct Stack<T> {
        var stack: [T] = []
        
        // 초기화 시 아무 값이 주어지지 않을때 동작하는 초기화
        init() {}
        
        // 초기화 시 값이 주어질때 동작하는 초기화
        init(_ element: [T]) {
            stack = element
        }
        
        // 데이터 저장
        mutating func push(_ element: T) {
            stack.append(element)
        }
        
        // 데이터 추출함과 동시에 제거
        mutating func pop() -> T? {
            return stack.popLast()
        }
        
        // 데이터 추출만
        func peek() -> T? {
            return stack.last
        }
        
        // 스택이 비었는지 판별
        func isEmpty() -> Bool {
            return stack.isEmpty
        }
        
        // 스택의 갯수 카운트
        func count() -> Int? {
            return stack.count
        }
    }
    
    // 스택을 출력할때 커스텀한 설명을 추가하는 프로토콜
    extension Stack: CustomStringConvertible {
        var description: String {
            return stack.description + "이 스택에 들어있습니다."
        }
    }
    
    // 스택 초기화 후 반복문 없이 배열로 스택을 넣을때 사용하는 프로토콜
    extension Stack: ExpressibleByArrayLiteral {
        init(arrayLiteral elements: T...) {
            for element in elements {
                stack.append(element)
            }
        }
    }
    
    var firstStack: Stack = Stack<Int>()
    var secondStack: Stack = Stack<Int>([1, 2, 3, 4])
    var thirdStack: Stack = Stack<Int>()
    
    firstStack = [2, 4, 6, 8]
    thirdStack.push(10)
    thirdStack.push(20)
    print("\(firstStack)" + "\n" + "\(secondStack)" + "\n" + "\(thirdStack)")

    위와 같이 다양하게 스택의 초기화를 두어 편하게 사용할 수 있습니다.

    스택의 push와 pop은 구조체의 프로퍼티에 값을 추가/삭제하여 변경됨으로 꼭 mutating 키워드를 붙여 프로퍼티를 변경할 수 있는 메서드라는걸 명시해줘야합니다.

    또한, CustomStringConvertible 프로토콜을 채택해 스택을 출력 시 원하는 설명을 커스텀하게 설정할 수 있습니다.

    마찬가지로 CustomDebugStringConvertible 프로토콜을 채택해 아래와 같이 사용하면 디버그 메시지에 대해 커스텀하게 설정할 수 있습니다.

    extension Stack: CustomDebugStringConvertible {
        var debugDescription: String {
            return stack.debugDescription + "이 스택의 디버그 설명입니다."
        }
    }

    마지막으로 초기화 시 값을 주어주지 않거나 매번 반복해서 값을 하나씩 주어주기 불편할때 ExpressibleByArrayLiteral 프로토콜을 사용할 수 있습니다.

    공식문서에도 나와있듯이 init 초기화 시 arrayLiteral을 통해 주어진 배열리터럴에서 배열을 만듭니다.

    만들어진 배열로 스택에 들어가게 초기화를 구현할 수 있습니다.

    이 속성을 사용하기위해 해당 프로토콜을 채택하여야합니다.

    'CS(ComputerScience)' 카테고리의 다른 글

    연결 리스트  (2) 2021.05.20
    큐 (Queue)  (0) 2021.05.19
    우선순위 큐  (2) 2021.05.17
    멀티프로세스 VS 멀티스레드  (0) 2021.04.30
    Cache  (0) 2021.02.04
Designed by Tistory.