Swift:我的散列 table 适用于幻数,但不适用于动态数
Swift: my hash table works with a magic number, but not with a dynamic number
我正在学习如何根据自己的知识创建自己的哈希 table(以及面试准备,让我们面对现实吧)。
我在 swift 工作,我 运行 陷入了一个我似乎无法很好解决的问题。
我们的目标是创建一个简单但有效的散列,在调整大小后仍然 returns 在输入键作为下标时的适当值。如果我在散列 table 中使用相同的值,无论其大小如何,它都会起作用。
例如,如果我将 %(模)除数设置为 3,那么一切都很好。散列 table 按预期工作。
但是……
如果我将 %(模)除数设置为 'buckets'.count Int 值,则在调整大小时,我的键不再映射到任何相关内容,我的 return 值为 'nil' 这是正确的,因为密钥映射到新调整大小的 'buckets' 中不存在的原始哈希值。
(我想我说的很对,如有不妥请见谅)
这是我对哈希函数的尝试:
// function to find a safe prime number -> a nice implementation i found here on stack overflow
func isPrime(_ n: Int) -> Bool {
guard n >= 2 else { return false }
guard n != 2 else { return true }
guard n % 2 != 0 else { return false }
return !stride(from: 3, through: Int(sqrt(Double(n))), by: 2).contains { n % [=12=] == 0 }
}
private func index(forKey key: Key) -> Int {
// set primeNumber to a value that is the largest Int value in range of buckets.count...0
var primeNumber: Int = 3
for n in 0...buckets.count {
let validPrime = isPrime(n)
if validPrime {
primeNumber = n
}
}
return abs(key.hashValue % primeNumber)
}
这是我对调整大小功能的尝试:
mutating func resize(newCapacity: Int) -> [Bucket] {
var temporaryBuckets: [Bucket] = []
for bucket in buckets {
temporaryBuckets.append(bucket)
}
self.capacity = newCapacity
assert(capacity > 0)
// need to find another way to re-insert the elements
buckets = Array<Bucket>(repeatElement([], count: capacity))
var index = 0
for bucket in temporaryBuckets {
buckets[index] = bucket
index += 1
}
return buckets
}
非常感谢任何帮助。如果有更有效的方法又不会太疯狂,那我洗耳恭听!
如果好奇,我正在尝试完成 Ray Wenderlich 的 Swift 算法俱乐部条目中的散列 table 教程:
Swift 算法俱乐部:Kelvin Lau 的哈希表。
https://www.raywenderlich.com/206-swift-algorithm-club-hash-tables
提前致谢!
您需要为新哈希重新计算索引table。现在,您正在将存储桶分配给索引 0、1、2 等等。相反,您应该为每个元素再次调用 index(forKey:)
并将其插入到新索引处。请注意,您现在不能使用相同的 Bucket
对象。你能想到这是为什么吗?
我正在学习如何根据自己的知识创建自己的哈希 table(以及面试准备,让我们面对现实吧)。
我在 swift 工作,我 运行 陷入了一个我似乎无法很好解决的问题。
我们的目标是创建一个简单但有效的散列,在调整大小后仍然 returns 在输入键作为下标时的适当值。如果我在散列 table 中使用相同的值,无论其大小如何,它都会起作用。
例如,如果我将 %(模)除数设置为 3,那么一切都很好。散列 table 按预期工作。
但是……
如果我将 %(模)除数设置为 'buckets'.count Int 值,则在调整大小时,我的键不再映射到任何相关内容,我的 return 值为 'nil' 这是正确的,因为密钥映射到新调整大小的 'buckets' 中不存在的原始哈希值。
(我想我说的很对,如有不妥请见谅)
这是我对哈希函数的尝试:
// function to find a safe prime number -> a nice implementation i found here on stack overflow
func isPrime(_ n: Int) -> Bool {
guard n >= 2 else { return false }
guard n != 2 else { return true }
guard n % 2 != 0 else { return false }
return !stride(from: 3, through: Int(sqrt(Double(n))), by: 2).contains { n % [=12=] == 0 }
}
private func index(forKey key: Key) -> Int {
// set primeNumber to a value that is the largest Int value in range of buckets.count...0
var primeNumber: Int = 3
for n in 0...buckets.count {
let validPrime = isPrime(n)
if validPrime {
primeNumber = n
}
}
return abs(key.hashValue % primeNumber)
}
这是我对调整大小功能的尝试:
mutating func resize(newCapacity: Int) -> [Bucket] {
var temporaryBuckets: [Bucket] = []
for bucket in buckets {
temporaryBuckets.append(bucket)
}
self.capacity = newCapacity
assert(capacity > 0)
// need to find another way to re-insert the elements
buckets = Array<Bucket>(repeatElement([], count: capacity))
var index = 0
for bucket in temporaryBuckets {
buckets[index] = bucket
index += 1
}
return buckets
}
非常感谢任何帮助。如果有更有效的方法又不会太疯狂,那我洗耳恭听!
如果好奇,我正在尝试完成 Ray Wenderlich 的 Swift 算法俱乐部条目中的散列 table 教程:
Swift 算法俱乐部:Kelvin Lau 的哈希表。 https://www.raywenderlich.com/206-swift-algorithm-club-hash-tables
提前致谢!
您需要为新哈希重新计算索引table。现在,您正在将存储桶分配给索引 0、1、2 等等。相反,您应该为每个元素再次调用 index(forKey:)
并将其插入到新索引处。请注意,您现在不能使用相同的 Bucket
对象。你能想到这是为什么吗?