获取一组对象的两个属性的最小值和最大值的最有效方法是什么

问题描述:

我正在编写一个应用程序,其中性能是最重要的,我必须遍历一组工作站,这些工作站都具有x - 和y坐标。这是工作站的相关部分和位置:获取一组对象的两个属性的最小值和最大值的最有效方法是什么

struct Workstation { 
    let position: Position 
} 

struct Position { 
    let x, y: Int 

    func distance(to otherPosition: Position) -> Int { 
     return abs(self.x - otherPosition.x) + abs(self.y - otherPosition.y) 
    } 
} 

在这种特定的情况下,我们的目标是让对角线周围的所有工作站的矩形的长度的一半,但我后来做了一些其他的计算(例如获取所有工作站的中心坐标)。

我想出了两种可能的解决方案(注:layout.workstationsSet<Workstation>类型):

解决方案1 ​​

private func getSurroundingRectangeScore(for layout: FactoryLayout) -> Double { 
    var minX = Int.max 
    var maxX = Int.min 
    var minY = Int.max 
    var maxY = Int.min 
    for workstation in layout.workstations { 
     let pos = workstation.position 
     if pos.x < minX { minX = pos.x } 
     if pos.x > maxX { maxX = pos.x } 
     if pos.y < minY { minY = pos.y } 
     if pos.y > maxY { maxY = pos.y } 
    } 
    let minPosition = Position(x: minX, y: minY) 
    let maxPosition = Position(x: maxX, y: maxY) 
    return Double(minPosition.distance(to: maxPosition))/2 
} 

解决方案2

private func getSurroundingRectangeScore(for layout: FactoryLayout) -> Double { 
    let xValues = layout.workstations.map { $0.position.x } 
    let yValues = layout.workstations.map { $0.position.y } 

    guard let minX = xValues.min(), let maxX = xValues.max(), let minY = yValues.min(), let maxY = yValues.max() else { 
     fatalError("Minima or Maxima could not be determined!") 
    } 

    let minPosition = Position(x: minX, y: minY) 
    let maxPosition = Position(x: maxX, y: maxY) 
    return Double(minPosition.distance(to: maxPosition))/2 
} 

我的理解是解决方案1遍历工作区只有一次,并在一次填充所有需要的坐标变量。解决方案2的可读性更好,但必须迭代两次工作站集合和最终的数组四次,所以我猜这是更糟糕的。所以我的问题是,如果我的假设是正确的,如果有更高效的计算方法?

+2

我认为O(n)对于这个问题来说可能是最好的复杂性,所以你的第一个解决方案可能就像它得到的那样好。 – Carcigenicate

+0

x和y坐标是否相互独立?如果他们是那么你将能够达到O(log n),这是显着更快。如果不是,那么恐怕O(n)最有可能是你最好的选择(当然,如果我正确理解你的问题,这当然没有看到应用程序/算法的其余要求) – TNguyen

+0

@ TPN1994:它们是独立的这个计算是的,因为我只需要所有x值和所有y值中的最小值来形成两个新的位置(与找到所有给定位置的最小和最大位置(x,y)相对比 - 这在此不需要) 。那么我将如何实现O(log n)呢? –

首先,不要猜测哪一个更糟。运行它并测量它。 (除了两者之外,还有一个选项,它使用内置的排序例程,然后查看结果的结尾。)

其次,如果要求访问此信息的速度始终尽可能快,然后使用支持该要求的数据结构。一次找到初始集合的值,然后在每次添加元素时更新它们。除了丢弃信息并重复进行相同的比较外,每次添加新的Workstation时只做四次。然后,每当你需要他们时,你都可以随时阅读四肢。

+0

对于一般的编码我相对比较陌生,效率是这个项目的第一次要求,所以你的回答对我有很大的帮助。在早期阶段解决这个问题,而不是在需要进行测量的地方进行,这并没有超出我的想法。我现在将以这种方式实施:) –

+1

太棒了,很高兴我能帮到你。也可以查看[“堆”](https://en.wikipedia.org/wiki/Heap_(data_structure))。 –