我挽救了许多词语的开头:
var n = 2
var a = [String]()
for w in words {
let part = prefix(w,n)
if !contains(a, part) {
a.append(part)
}
}
对于一些英语单词,这需要花费很多时间。是否有任何快速内置的String / Array / Set解决方案来更快地完成这项工作?
编辑:感谢您的提示,我可以将这些想法与更好的表现相结合:
let words2 = words.map{prefix($0, n)}
var a = [String]()
var last = ""
for w in words2 {
if w != last {
a.append(w)
}
last = w
}
首先它创建一个2字符数组。在循环中,我可以简单地将项目与前一个项目进行比较,而无需进一步的字符串操作!似乎很棒。还有更先进的快速改进吗?
答案 0 :(得分:1)
如果您无法保证words
数组已排序,我将实施以下解决方案:
let prefixesSet = Set(words.map { prefix($0, length) })
鉴于n
:words.count
map
的调用需要时间O(n)
我不知道initializer
的{{1}}是如何实现的。我可以想象几个场景:
Set
会对输入数组进行时间initializer
排序,然后将每个元素添加到O(n log n)
丢弃重复项Set
(排序后是连续的)。
此方案的总时间:O(n log n) O(n)
并使用Set
编制索引,其中密钥为字词本身的hash map
。这里效率与碰撞成反比。碰撞我指的是碰巧有两个不同的单词hashValue
。
但是我除了Cocoa之外对字符串有很好的hashValue
实现,所以我认为在这种情况下时间可能接近 O(n)。正如我之前所说,如果您无法保证hashValue
已排序,则适用此选项。另一方面,如果words
已排序,我认为您的第二个代码块代表了最佳方法。它只需要时间 O(n)。