A
给定一个由正整数组成且不存在重复数字的数组 ,找出和为给定目标正整数
的组合的个数。
动态规划法
建立 数组,设
的长度为
。其中
。
从 开始推导,最后的
即为期望结果。
回溯法
从 开始往前推算,同样是遍历
,但只计算
的值,每次计算时调用函数递归计算,直到
时再往上合并。
为了避免重复计算 的值,可以用一个
map 将计算过的值保存起来。
两种方法的对比
动态规划法只需要调一个函数,无需创建大量对象,即可计算出结果。但是会计算出一些不需要计算的 的值。
回溯法在配上 map 后,可以最小化计算的 数,只计算必需会用到的值。理论上比动态规划法更好,但是实际运行中,除去函数的嵌套调用层级容易过深,不利于 debug 外,多次的嵌套调用会创建很多对象,实际用时通常会比动态规划法更慢。
R
Avoiding Callback Hell in Swift
文章介绍几种避免陷入回调地狱的方法。
Promises
这是一个第三方库,通过使用其包含的 then(completion:) 和 catch(completion:) 方法来简化层级,参考示例如下:
func perform<T: Request>(request: T) -> Promise<T.Response>
return Promise { promise in
//Do the actual request here, then:
promise.fulfill(response)
}
}
perform(requestOne()).then { responseOne in
perform(requestTwo(responseOne: responseOne))
}.then { responseTwo in
perform(requestThree(responseTwo: responseTwo))
}.then { responseThree in
perform(requestFour(responseThree: responseThree))
}.catch { error in
print(error)
}.always {
print("Finished")
}
它可以有效避免嵌套的回调地狱出现,但是需要引用第三方库。
OperationQueue
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
func doLotsOfStuff(completion: (() -> Void)?) {
let firstOperation: Operation = FirstOperation()
let secondOperation: Operation = SecondOperation()
secondOperation.completionBlock = {
completion?()
}
secondOperation.addDependency(firstOperation)
queue.addOperation(firstOperation)
queue.addOperation(secondOperation)
}
Foundation 里自带的方法,可以在一定程度上减少回调层级,但是如果 queue 里有网络请求,或者 operation 依赖于前一个的返回值,就无法使用了。
虽然可以通过预先创建 data 对象,作为参数传入给每个 operation 或在自定义的 operation 类创建数据对象,在调用时从 dependencies 里查找,但是并不是一种好的实现。
高阶函数
let sum = array.reduce(0, +)
//reduce() here is an ((Int, ((Int, Int) -> Int)) -> Int)
//and the + operator is func +(lhs: Int, rhs: Int) -> Int,
//... or ((Int, Int) -> Int), so there's no need to define reduce's closure.
将方法对象做为闭包参数传递,可以减少方法中嵌套闭包的数量。但是要求先创建闭包对象,不便于阅读。
T
Swift 闭包可以通过 $0 和 $1 等来表示闭包中的第1,2 个参数,使用时其对应的参数类型也会根据函数类型判断。
let numbers = [1,2,5,4,3,6,8,7]
let sortNumbers = numbers.sorted(by: { (a, b) -> Bool in
return a < b
})
let numbers = [1,2,5,4,3,6,8,7]
let sortNumbers = numbers.sorted(by: {$0 < $1})