A
描述: 反转一个单链表。
思路: 使用 pre 保存向前的位置,再用 temp 保存向后的位置。一次遍历就能整体反转了。
R
Swift 中不少地方使用到了 Hashable ,如 Dictionary 的 key ,Set 里的元素,都需要是 Hashable 的。
@frozen struct Dictionary<Key, Value> where Key : Hashable
@frozen struct Set<Element> where Element : Hashable
Hashing 是什么和为什么要用?
定义
Hash 是应用一种算法将数据项转换为一个值的过程,这种算法被称为 Hash 函数,转换后的值称为 hash value ,hash code 或简称为 hash 。
整个过程具体以下特性。
hashing过程是可重复的,重复结果不变。hash值是唯一的。hash应当近似随机,最小化反转的可能性。hash值类型没有限制,可以是负整数,也可能包含数字、字符和符号。
使用范围
- 数据库的搜索
- 密码加密
- 编程中的字典数据结构
可以有效提升查询速度和安全性。
Hashable Protocol
官方文档的定义如下:
“A type that can be hashed into a Hasher to produce an integer hash value.”
Type
可哈希协议是在类型级别实现的,所以所有的实例都是可哈希的。
Hasher
它实际上是一个 struct ,可以通过 var hasher = Hasher() 来实例化。
Swift 中使用的通用哈希函数是 SipHash 。
Integer
-
因为有整数溢出,所以值可能为负数。
-
由于哈希函数的种子不同,程序的每次执行中生成的哈希值也可能不同,不能将其用于下次执行时做对比。
-
它是继承自
Euqatable,所以Hashable的数据同时敢是Equatable的。 -
常用解决碰撞冲突的方法。
- 链接引用。
- 线性探测。
使用 Hashable Protocol
如果期望使用某个数据结构作为 Dictionary 的 Key ,就需要在数据结构里实现 Hashable Protocol
struct Student {
var firstName: String
var lastName: String
}
extension Student : Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(firstName)
hasher.combine(lastName)
}
}
需要注意的事,函数中不需要调用 finalize 函数,编译器会在使用到哈希值时自动调用。
自动哈希
在 Swift 4.1 中,编译器为哈希函数提供了自动实现,如果它的属性均是 Hashable 的,就不需要再手动实现哈希函数,编译器会自动实现。
struct Student : Hashable {
var firstName: String
var lastName: String
}
T
Swift 中遍历时同时遍历 index 和元素
let array = ["a","b","c","d"]
for (index, element) in array.enumerated() {
print("/(index)--/(element)")
}
S
无