hello-algo/codes/swift/chapter_hashing/hash_map_open_addressing.swift
nuomi1 7f8b0fff54
feat: add Swift codes for hash_collision article (#569)
* feat: add Swift codes for hash_collision article

* refactor: extract common Pair

* Update hash_map.md

---------

Co-authored-by: Yudong Jin <krahets@163.com>
2023-07-01 20:39:55 +08:00

158 lines
4.6 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* File: hash_map_open_addressing.swift
* Created Time: 2023-06-28
* Author: nuomi1 (nuomi1@qq.com)
*/
import utils
/* */
class HashMapOpenAddressing {
var size: Int //
var capacity: Int //
var loadThres: Double //
var extendRatio: Int //
var buckets: [Pair?] //
var removed: Pair //
/* */
init() {
size = 0
capacity = 4
loadThres = 2 / 3
extendRatio = 2
buckets = Array(repeating: nil, count: capacity)
removed = Pair(key: -1, val: "-1")
}
/* */
func hashFunc(key: Int) -> Int {
key % capacity
}
/* */
func loadFactor() -> Double {
Double(size / capacity)
}
/* */
func get(key: Int) -> String? {
let index = hashFunc(key: key)
// 线 index
for i in stride(from: 0, to: capacity, by: 1) {
//
let j = (index + i) % capacity
// key nil
if buckets[j] == nil {
return nil
}
// key val
if buckets[j]?.key == key, buckets[j] != removed {
return buckets[j]?.val
}
}
return nil
}
/* */
func put(key: Int, val: String) {
//
if loadFactor() > loadThres {
extend()
}
let index = hashFunc(key: key)
// 线 index
for i in stride(from: 0, through: capacity, by: 1) {
//
let j = (index + i) % capacity
//
if buckets[j] == nil || buckets[j] == removed {
buckets[j] = Pair(key: key, val: val)
size += 1
return
}
// key val
if buckets[j]?.key == key {
buckets[j]?.val = val
return
}
}
}
/* */
func remove(key: Int) {
let index = hashFunc(key: key)
// 线 index
for i in stride(from: 0, to: capacity, by: 1) {
//
let j = (index + i) % capacity
// key
if buckets[j] == nil {
return
}
// key
if buckets[j]?.key == key {
buckets[j] = removed
size -= 1
return
}
}
}
/* */
func extend() {
//
let bucketsTmp = buckets
//
capacity *= extendRatio
buckets = Array(repeating: nil, count: capacity)
size = 0
//
for pair in bucketsTmp {
if let pair, pair != removed {
put(key: pair.key, val: pair.val)
}
}
}
/* */
func print() {
for pair in buckets {
if let pair {
Swift.print("\(pair.key) -> \(pair.val)")
} else {
Swift.print("null")
}
}
}
}
@main
enum _HashMapOpenAddressing {
/* Driver Code */
static func main() {
/* */
let map = HashMapOpenAddressing()
/* */
// (key, value)
map.put(key: 12836, val: "小哈")
map.put(key: 15937, val: "小啰")
map.put(key: 16750, val: "小算")
map.put(key: 13276, val: "小法")
map.put(key: 10583, val: "小鸭")
print("\n添加完成后,哈希表为\nKey -> Value")
map.print()
/* */
// key value
let name = map.get(key: 13276)
print("\n输入学号 13276 ,查询到姓名 \(name!)")
/* */
// (key, value)
map.remove(key: 16750)
print("\n删除 16750 后,哈希表为\nKey -> Value")
map.print()
}
}