本文是对 万字长文对Swift语法一网打尽 精简版, 重点语法特别是和算法有关的语法调出, 速记速看.
github中的 swift俱乐部涉及到的算法总结
字符串
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex let beginning = greeting[..<index]
// 把结果转化为 String 以便长期存储。 let newString = String(beginning)”
let index1:String.Index = stre.index(before: stre.endIndex) let index2:String.Index = stre.index(stre.endIndex, offsetBy: -2) let str22 = stre[index2...index1]
// ... 运算符指定范围,从 startIndex 向后移动4位截取子串 var subStr = indexStr[startIndex...indexStr.index(startIndex, offsetBy: 4)] // hello // 从endIndex 向前移动7位截取子串 var subStr2 = indexStr[indexStr.index(endIndex, offsetBy: -7)..<endIndex] // William
indexStr.index(startIndex, offsetBy: 4)
endIndex, offsetBy: -7
isEmpty
count 字符串个数
<==
String.Index
三) 数组
2个相同类型的数组相加 +
array.append(contentsOf: [10, 11, 12]) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
// 在指定位置插入单个元素 array.insert(0, at: 0) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] // 在指定位置插入一组元素 array.insert(contentsOf: [-3, -2, -1], at: 0) // [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] // 移除指定元素 array.remove(at: 1) // -2
array.removeFirst() // 1
array.removeLast(3) // [5, 6, 7, 8]
array.replaceSubrange(0...3, with: [1, 2, 3, 4]) // [1, 2, 3, 4]
sortArr.sorted(by: <) // [-1, 1, 2, 3]
sortArr.min() // -1
for item in arr { print(item) } // 打印数组的下标及对应元素 for item in arr.enumerated() { print(item) // (offset: 0, element: 11) (offset: 1, element: 22) (offset: 2, element: 33) } // 下标遍历 for index in arr.indices { print(arr[index]) }
四 Swift 集合 Set 及常用方法
1.var set: Set<Int> = [1, 2, 3]
2. var set2 = Set(arrayLiteral: 1, 2, 3)
set.first
set[set.index(after: set.startIndex)] // 获取某个下标后几个元素 set[set.index(set.startIndex, offsetBy: 2)]
- 常用方法
// 获取元素个数 set.count
.isEmpty
if (set.contains(3)) {
set.removeFirst()
// 判断 Set 集合相等 if eqSet1 == eqSet2 { print("集合中所有元素相等时,两个集合才相等,与元素的顺序无关") }
// Set 取交集 setStr1.intersection(setStr2) // {"2", "1"} // Set 取交集的补集
setStr1.symmetricDifference(setStr2) // {"4", "5", "3", "6"} // Set 取并集
setStr1.union(setStr2) // {"2", "3", "1", "4", "6", "5"} // Set 取相对补集(差集),A.subtract(B),即取元素属于 A,但不属于 B 的元素集合
setStr1.subtract(setStr2) // {"3", "4"}
遍历
// 遍历元素 for ele in set4 { print(ele) } // 遍历集合的枚举 for ele in
set4.enumerated() { print(ele) } // 下标遍历 for index in set4.indices {
print(set4[index]) } // 从小到大排序后再遍历 for ele in set4.sorted(by: <) {
print(ele) }
四) Swift 字典 Dictionary 集合类型
var emptyDict1: [Int : String] = [:]
var emptyDict2: Dictionary<Int, String> = Dictionary()
var dict2: Dictionary<Int, String> = Dictionary(dictionaryLiteral: (1, "One"), (2, "Two"))
var dic1=[1:1,2:12,3:32,4:16,5:15] var dic2:Dictionary<String,String>=[:]
- 获取元素
dict[0] = "000" // 000
// 获取元素个数 dict.count // 3
// 判断字典为空 dict.isEmpty // false
if let lastValue = dict.updateValue("new one", forKey: 1) {
dict.removeValue(forKey: -1) // -1
- 遍历字典
// 遍历字典的键 for ele in dict.keys { print(ele) } // 遍历字典的值 for ele in dict.values { print(ele) } // 元组遍历,直接获取键值对 for (key, val) in dict { print("\(key):\(val)") } // 对 key 进行从小到大排序后遍历,并对值进行拆包 for ele in dict.keys.sorted(by: <) { print(dict[ele]!) }
六) Swift 运算符、循环、流程控制 for-in, while, if-else, switch-case, guard-else
// switch 子句多条件匹配 switch caseStr { case "a","b","c": print("match success") default: print("default value") }
// switch 子句区间范围匹配 let age = 18 switch age { case 16..<18: print("match age 16...18") case 18...20: print("match age 18..<20") default: print("default value") }
七) Swift 函数与闭包
// 创建函数,带参,返回类型为 Optional func func4(param: Int) -> Int? { guard param > 2 else { return nil } return param + 2 }
- 函数内外参数命名
func mutableParamFunc(param: Int...)
{
var sum = 0
for ele in param
{
sum += ele
}
print(sum)
}
let func7Name: (Int, Int) -> Bool // 将闭包赋值给函数变量 func7Name = {(param1: Int, param2: Int) in return param1 > param2 } // 调用函数变量 func7Name(1, 2) // false
// 函数作为返回值类型 func func9() -> (Int, Int) -> Bool { return func7Name // 将 func7Name 返回 }
八) Swift5 高级[运算符]与枚举
var sixteen: UInt8 = 0b00010000 // 二进制
- 溢出运算符
var result12 = num &+ 1 // 溢出后变为0
// 定义字符串枚举,原始值类型为 String enum Week: String { // 在一行中直接定义,也可以分别使用 case 定义 case MON = "星期一", TUE = "星期二", WED = "星期三", THUR = "星期四", FRI = "星期五", SAT = "星期六", SUN = "星期日" }
// case 需要详尽列出
switch day {
case .MON: print("monday", day.rawValue) // monday 星期一 case .TUE: print("tuesday")
case .WED:
print("wednesday")
case .THUR:
print("thursday")
case .FRI:
print("friday")
case .SAT:
print("saturday")
case .SUN:
print("sunday")
}
九) Swift 结构体与类
struct Phone { // 定义价格属性 var price: Int // 定义品牌属性 var brand: String // 定义型号属性 var model: String // 定义降价促销方法 mutating func discount() { price -= 800 } }
// 调用默认的构造方法,创建结构体实例
let iPhone = Phone(price: 6999, brand: "iPhone", model: "iPhone 13")
print("手机品牌:\(iPhone.brand), 型号:\(iPhone.model),价格:\(iPhone.price)" )
- 类
// 定义一个类 class PhoneClass
{
// 定义价格属性 var price: Int = 0 // 定义品牌属性 var brand: String = "" // 定义型号属性 var model: String = ""
// 定义降价促销方法 func discount() { price -= 800 }
// 当三个属性都有默认值的时候,可以不写
init init(price: Int, brand: String, model: String) { self.price = price
self.brand = brand self.model = model } }
十) Swift5 属性与方法
class Phone {
var system = "iOS" // 常量存储属性,一旦实例化,不能修改 let brand:
String // 存储属性,可以修改 var price: Int // 当类被实例化时,要保证所有的属性都初始化完成,除非属性有默认值
init(brand: String, price: Int)
{
self.brand = brand
self.price = price
print("brand: \(brand), price: \(price)")
}
}
// 修改类的属性值 let iPhone = Phone(brand: "iPhone", price: 5999) iPhone.price -= 600
- Swift 计算属性
- Swift 静态属性与静态方法
十一) Swift5 [构造方法]
1.1. Swift 类的构造方法
4. Swift 构造方法的安全性检查
使用 stride(from:to:by:) 函数跳过不需要的标记。
let minuteInterval = 5
for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
// 每5分钟渲染一个刻度线(0, 5, 10, 15 ... 45, 50, 55)
}
使用 stride(from:to:by:) 和使用 stride(from:through:by:)的区别,
以上例子解释:前者范围\[0,60)不包括minutes,后者范围\[0,60]包括minutes
十三 ) Swift5 类型转换泛型、扩展与协议
1. Swift 判断值类型
6. Swift 泛型约束
struct ObjList<T: Base> {
private var datas: [T] = []
swift俱乐部涉及到的算法总结
书籍中涉及的swift算法
@discardableResult
chapter_array_and_linkedlist
// 在区间 [0, nums.count) 中随机抽取一个数字
let randomIndex = nums.indices.randomElement()!
//https://developer.apple.com/documentation/swift/defaultindices/randomelement()
// 将原数组中的所有元素复制到新数组
for i in nums.indices {
res[i] = nums[i]
}
// 把索引 index 以及之后的所有元素向后移动一位
for i in sequence(first: nums.count - 1, next: { $0 > index + 1 ? $0 - 1 : nil }) {
nums[i] = nums[i - 1]
}
/* 删除索引 index 处元素 */
func remove(nums: inout [Int], index: Int) {
let count = nums.count
// 把索引 index 之后的所有元素向前移动一位
for i in sequence(first: index, next: { $0 < count - 1 - 1 ? $0 + 1 : nil }) {
nums[i] = nums[i + 1]
}
}
chapter_backtracking
/* Driver Code */
static func main() {
if !selected[i], !duplicated.contains(choice) {
var res: [[TreeNode]] = []
backtrack(state: &state, choices: [root].compactMap { $0 }, res: &res)
chapter_binary_search
chapter_computational_complexity
let nodes = (0 ..< n).map { ListNode(x: $0) }
func linear(n: Int) {
// 长度为 n 的数组占用 O(n) 空间
let nums = Array(repeating: 0, count: n)
// 长度为 n 的列表占用 O(n) 空间
let nodes = (0 ..< n).map { ListNode(x: $0) }
// 长度为 n 的哈希表占用 O(n) 空间
let map = Dictionary(uniqueKeysWithValues: (0 ..< n).map { ($0, "\($0)")
}
for i in stride(from: nums.count - 1, to: 0, by: -1) {
for _ in stride(from: 0, to: n, by: 1) {
@main
enum WorstBestTimeComplexity {
chapter_graph
let v = Vertex.valsToVets(vals: [1, 3, 2, 5, 4])
// 邻接表,key: 顶点,value:该顶点的所有邻接顶点
public private(set) var adjList: [Vertex: [Vertex]]
adjList[key]?.removeAll(where: { $0 == vet })
#if !TARGET
@main
for adjVet in graph.adjList[vet] ?? [] {
chapter_hashing
private var buckets: [Entry?] = []
chapter_heap
if l < size(), maxHeap[l] > maxHeap[ma] {
Binary Tree ,chapter_searching
for i in nums.indices.dropLast() {
for j in nums.indices.dropFirst(i + 1) {
chapter_sorting
for i in stride(from: nums.count - 1, to: 0, by: -1) {
var buckets = (0 ..< k).map { _ in [Double]() }
init() {}
for i in sequence(first: res.count - 1, next: { $0 >= 0 + 1 ? $0 - 1 : nil }) {
/* 执行旋转操作,使该子树重新恢复平衡 */
private func rotate(node: TreeNode?) -> TreeNode? {
// 获取节点 node 的平衡因子
let balanceFactor = balanceFactor(node: node)
// 左偏树
if balanceFactor > 1 {
if self.balanceFactor(node: node?.left) >= 0 {
// 右旋
return rightRotate(node: node)
} else {
// 先左旋后右旋
node?.left = leftRotate(node: node?.left)
return rightRotate(node: node)
}
}
// 右偏树
if balanceFactor < -1 {
if self.balanceFactor(node: node?.right) <= 0 {
// 左旋
return leftRotate(node: node)
} else {
// 先右旋后左旋
node?.right = rightRotate(node: node?.right)
return leftRotate(node: node)
}
}
// 平衡树,无需旋转,直接返回
return node
}
swift 算法
1-10 ()3Sum and 4Sum - Bloom Filter)
// `precondition(_:_:file:line:)`函数类似`assert`,满足条件会造成程序的提前终止并抛出错误信息,详细查看[官方文档](https://developer.apple.com/documentation/swift/1540960-precondition)。
public class TreeNode<Key: Comparable, Payload> {
fileprivate(set) var root: Node?
fileprivate(set) var size = 0
public init() { }
public func insert(key: Key, payload: Payload? = nil) {
public var description: String {
return root?.description ?? "[]"
} weak fileprivate var parent: Node?
internal var leftChild: Node?
extension TreeNode: CustomDebugStringConvertible {
class BTreeNode<Key: Comparable, Value> {
public init?(order: Int) {
guard order > 0 else {
print("Order has to be greater than 0.")
return nil
}
self.order = order
rootNode = BTreeNode<Key, Value>(owner: self)
}
11-20 (Bounded Priority Queue - Counting Sort)
21-30 (Depth-First Search - Graph)
31-40 (Hash Set - K-Means)
41-50 (Karatsuba Multiplication - Minimum Spanning Tree)
51-60 (Minimum Spanning Tree(Unweighted - Priority Queue)
61-70 (QuadTree - Segment Tree)
71-80 (Select Minimum Maximum - Skip-List)
81-90 (Slow Sort - Two-Sum Problem)
91-100 (Union-Find - Z-Algorithm )