我正在尝试转换以下 Swift 2.3 代码:
//Example usage:
//(0 ..< 778).binarySearch { $0 < 145 } // 145
extension CollectionType where Index: RandomAccessIndexType {
/// Finds such index N that predicate is true for all elements up to
/// but not including the index N, and is false for all elements
/// starting with index N.
/// Behavior is undefined if there is no such N.
func binarySearch(predicate: Generator.Element -> Bool)
-> Index {
var low = startIndex
var high = endIndex
while low != high {
let mid = low.advancedBy(low.distanceTo(high) / 2)
if predicate(self[mid]) {
low = mid.advancedBy(1)
} else {
high = mid
}
}
return low
}
}
进入 Swift 3 如下:
//Example usage:
//(0 ..< 778).binarySearch { $0 < 145 } // 145
extension Collection where Index: Strideable {
/// Finds such index N that predicate is true for all elements up to
/// but not including the index N, and is false for all elements
/// starting with index N.
/// Behavior is undefined if there is no such N.
func binarySearch(predicate: (Generator.Element) -> Bool)
-> Index {
var low = startIndex
var high = endIndex
while low != high {
let mid = low.advanced(by: low.distance(to: high) / 2)
if predicate(self[mid]) {
low = mid.advanced(to: 1)
} else {
high = mid
}
}
return low
}
}
错误
Binary operator '/' cannot be applied to operands of type 'self.Index.Stride' and 'Int'
在 let mid = low.advanced(by: low.distance(to: high)/2)
有任何关于如何修复它的帮助吗?
最佳答案
在 Swift 3 中,“Collections move their index”,比较
A New Model for Collections and Indices关于 Swift 进化。特别是,您不会在索引上调用 advancedBy()
,
但是在集合上使用 index()
方法来推进索引。
所以你的方法将在 Swift 3 中实现为
extension RandomAccessCollection {
func binarySearch(predicate: (Iterator.Element) -> Bool) -> Index {
var low = startIndex
var high = endIndex
while low != high {
let mid = index(low, offsetBy: distance(from: low, to: high)/2)
if predicate(self[mid]) {
low = index(after: mid)
} else {
high = mid
}
}
return low
}
}
同样的方法也可以作为
更通用的 Collection
类型,但是——正如 Vadim Yelagin 正确评论的那样,
如果无法完成索引/偏移量计算,则效率非常低
常数时间。
关于swift - 跨步协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40226479/