首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >要扩展哪种Swift收集协议以添加二进制搜索

要扩展哪种Swift收集协议以添加二进制搜索
EN

Stack Overflow用户
提问于 2017-06-01 01:41:33
回答 1查看 323关注 0票数 1

我想实现一些二进制搜索,比如对可随机访问(在固定时间内)的有序元素集合进行操作的函数,并且支持索引算法(用于导出中间点)。我可以将这些方法作为扩展或Array添加。但是,我更喜欢将它们添加到支持必要功能的更通用的协议中,这样我的扩展就可以得到更广泛的使用。

我应该使用哪种协议,以及将来如何查找这样的协议?我搜索了"Swift collection protocol hierarchy“和类似的内容,除了各种转移注意力的问题之外,我没有找到任何有用的东西。

EN

回答 1

Stack Overflow用户

发布于 2017-06-01 02:20:24

对于二进制搜索,您需要找到两个索引位置之间的“中点”,这对于任何Collection都是可能的,因为它关联的IndexDistance必须是SignedInteger

一种可能的实现(取自https://stackoverflow.com/a/40226976/1187415)是

代码语言:javascript
复制
extension Collection {

    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
    }
}

这里distance(from:to:)返回一个可以被2整除的IndexDistance,因为它符合SignedInteger (因此也符合IntegerArithmetic),结果可以在index(_:offsetBy:)中使用。

这两种方法的文档都说明了复杂性是

如果集合符合RandomAccessCollection,则返回O(1);否则为O( n ),其中n是n的绝对值。

因此,如果您希望保证它仅用于移动索引和测量距离是O(1)操作的集合,则可以将其实现为RandomAccessCollection的扩展。

或者您将其实现为Collection的扩展,这样它就可以被普遍使用。当在RandomAccessCollection上调用时,它将是“快”的(在上面的意义上),否则可能是“慢”的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44291405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档