我正在寻找一种更有效的解决方案,以在Swift中详尽地比较同一数组的对象与每个对象。嵌套for-in循环非常详尽,简单,并且返回正确的结果,但是时间复杂度为O(n ^ 2),在性能和更大的数据集方面,没有人建议这样做。我寻找了很长时间的解决方案,然后才发现有人将for-in循环场景描述为二次时间复杂度的经典示例。帮助吗?
编辑(现在包括func tableView(tableView:cellForRowAt :)代码):
好吧,根据要求深入了解。
考虑一下UITableView,其中有一个Event对象数组。
Event是一个类,您想详尽地检查数组的Event对象是否相互冲突。
该数组已按每个Event元素的startTike属性按时间顺序排序。可能会有重复的事件,因为用户可能希望这样做(知道原因,但这是最终用户的选择)。
每个事件对象都有此检查的DateInterval属性。
如果发现冲突,则需要运行逻辑以评估冲突。
如果满足某些条件,则可以在Event对象上设置一个布尔属性(isConflicted)。
然后,将所得数组用于将indexPath.row特定的Event对象传递到自定义UITableViewCell,以在UITableView中进行展示,其中“ isConflicted”布尔值是UITableViewCell的布局/演示所不可缺少的。
尽管运行时复杂度不是很高,但这里的嵌套循环解决方案我工作得很好。
很抱歉,没有更早地包含代码。我错误地认为没有必要。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// unwrap my custom cell
guard let cell = tableView.dequeueReusableCell(withIdentifier: "eventCell", for: indexPath) as? EventDetailTableViewCell else {
return UITableViewCell()
}
// get the relevant section's events array from EventModelController.shared.groupedEventsDictionary check for nil
guard let events = EventModelController.shared.groupedEventsDictionary[sections[indexPath.section]] else {
print("ERROR: no event value found in EventModelController.shared.groupedEventsDictionary[sections[indexPath.section]] in EventsTableViewController.swift -> tableView(cellForRowAt:) - line 117.")
return UITableViewCell()
}
var eventDictionary: [DateInterval : Event] = [:]
for event in events {
eventDictionary[event.dateInterval] = event
}
// START: - option with time complexity O(n^2) that always works
// check the array for conflicts and set relevant event's isConflicted property
for event in events {
for anotherEvent in events {
// ensure that we don't redundantly check the same events against themselves
if event != anotherEvent {
if event.dateInterval.intersects(anotherEvent.dateInterval) {
if event.stopTime == anotherEvent.startTime || event.startTime == anotherEvent.stopTime {
event.isConflicted = false
} else {
event.isConflicted = true
}
}
}
}
}
// END: - option with time complexity O(n^2) that always works
// Configure the cell...
cell.event = events[indexPath.row]
return cell
}
答案 0 :(得分:0)
有一个建议。
extension Array where Element: Hashable {
var containsDouplicated: Bool {
Set<Element>.init(self).count < self.count
}
}
我创建此扩展是为了使用Set的功能来消除重复的值,然后我检查了set(仅具有唯一值)是否具有相同数量的元素。 我认为这是O(2n),所以O(n)。
有一个使用方法的示例。
let a1 = [1,2,3]
let a2 = [1,2,3,4,1]
a1.containsDouplicated // false
a2.containsDouplicated // true
extension Array where Element: Hashable {
var containsDouplicated: Bool {
Set<Element>.init(self).count < self.count
}
}
编辑:编辑后,我建议您制作Event : Hashable
并实施一种:
extension Array where Element: Hashable {
var containsDouplicates: Bool {
Set<Element>.init(self).count < self.count
}
var orderedUniqueElements: [Element] {
var uniq: Set<Element> = .init(self)
let filtered: [Element] = self.filter { element -> Bool in
if !uniq.contains(element) {
return false
} else {
uniq.remove(element)
}
return true
}
return filtered
}
}
为了保留indexPath。