Post

Hash

Hash

Swift에서 해시(Hash)의 개념과 사용 예제

1. 해시(Hash)란?

Image

해시(Hash)는 데이터를 해시 함수(Hash Function)를 사용하여 고유한 숫자로 변환한 후, 해당 숫자를 기준으로 값을 저장하고 검색하는 방식이다.

Swift에서는 SetDictionary가 내부적으로 해시 테이블(Hash Table)을 사용하여 데이터를 저장하고 검색한다.

2. 해시를 사용하는 이유

  • 빠른 검색 속도: 해시 값을 이용하면 데이터를 O(1)의 시간 복잡도로 빠르게 찾을 수 있다.
  • 중복 없는 저장: Set을 사용하면 자동으로 중복이 제거된다.
  • 키-값 저장 구조: Dictionary는 키를 해시로 변환하여 데이터를 저장하므로, 키를 이용해 빠르게 값을 찾을 수 있다.

3. 해시 테이블의 동작 원리

  1. 값을 해시 함수에 넣어 해시 값을 생성

    1
    
     hash("Apple")  12345  // 해시 함수가 문자열을 고유한 숫자로 변환
    
  2. 해시 값을 기반으로 저장 위치를 결정

    1
    2
    
     해시 테이블:
     [ 12345: "Apple" ]
    
  3. 검색 시에도 같은 해시 값을 사용하여 빠르게 찾음

    1
    
     hash("Apple")  12345  // 동일한 해시 값으로 검색
    

4. Swift에서 해시를 활용하는 자료구조

4.1 Set (중복 없는 데이터 저장 & 빠른 검색)

Swift의 Set은 해시 테이블을 사용하여 값을 저장하므로 중복을 허용하지 않고, O(1)의 시간 복잡도로 빠르게 검색할 수 있다.

1
2
3
var uniqueNames: Set<String> = ["Alice", "Bob", "Charlie"]
print(uniqueNames.contains("Bob"))  // true (해시 값을 이용한 빠른 검색)

4.2 Dictionary (키-값 쌍 저장 & 빠른 검색)

Dictionary는 키를 해시로 변환하여 값을 저장하므로, 특정 키를 이용해 값을 빠르게 찾을 수 있다.

1
2
3
var studentScores: [String: Int] = ["Alice": 90, "Bob": 85, "Charlie": 95]
print(studentScores["Bob"]!)  // 85 (해시 값을 이용한 빠른 검색)

5. Hashable 프로토콜

Swift에서 Set이나 Dictionary에 저장되는 값은 반드시 Hashable 프로토콜을 준수해야 한다.

이는 Swift가 내부적으로 해시 값을 계산하고, 해시 테이블에서 데이터를 효율적으로 저장할 수 있도록 하기 위함이다.

5.1 Hashable을 준수하지 않으면 오류 발생

1
2
3
4
5
6
7
8
9
10
11
12
class Person {
    let name: String
    init(name: String) {
        self.name = name
    }
}

let person1 = Person(name: "Alice")
let person2 = Person(name: "Bob")

var peopleSet: Set<Person> = [person1, person2]  // 오류 발생!

오류 발생: "Person" does not conform to "Hashable"

5.2 Hashable을 준수하여 사용 가능하게 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Person: Hashable {
    let name: String

    init(name: String) {
        self.name = name
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(name)  // 해시 값을 계산하는 방식 정의
    }

    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.name == rhs.name
    }
}

let person1 = Person(name: "Alice")
let person2 = Person(name: "Bob")

var peopleSet: Set<Person> = [person1, person2]  // 정상 동작

PersonHashable을 준수하면 Set이 해시 값을 생성할 수 있어 저장 가능해진다.

6. 정리

  1. 해시(Hash)는 값을 특정한 고유 숫자로 변환하여 저장하는 방식이다.
  2. SetDictionary는 해시 테이블을 사용하여 데이터를 O(1)의 시간 복잡도로 빠르게 검색한다.
  3. Set은 중복을 허용하지 않는 컬렉션이며, Dictionary는 키-값 쌍을 저장하는 컬렉션이다.
  4. SetDictionary에 저장되는 값은 반드시 Hashable 프로토콜을 준수해야 한다.
  5. Hashable을 준수하지 않으면 SetDictionary에 저장할 수 없으며, 직접 hash(into:) 메서드를 구현해야 한다.

이제 Swift에서 해시(Hash)를 활용하여 빠르고 효율적인 데이터 구조를 만들 수 있다.

This post is licensed under CC BY 4.0 by the author.