获取数组的中位数。

14

我有一个看起来像这样的数组:

let arr = [1,2,3,4,5,6,7,8,9]

我知道你可以通过以下方式获取minmax

let min = arr.min()
let max = arr.max()

但是你如何获得中位数?


1
如果你的数组是 [1,2,3,4,5,6,7,8] 呢? - Nirav D
https://forums.swift.org/t/median/52279 - pkamb
5个回答

23

要获得 中位数,您可以使用以下方法:

let median = arr.sorted(by: <)[arr.count / 2]

在您的情况下,它将返回5

正如@Nirav指出的那样,[1,2,3,4,5,6,7,8]将返回5,但应该返回4.5

请改用以下内容:

func calculateMedian(array: [Int]) -> Float {
    let sorted = array.sorted()
    if sorted.count % 2 == 0 {
        return Float((sorted[(sorted.count / 2)] + sorted[(sorted.count / 2) - 1])) / 2
    } else {
        return Float(sorted[(sorted.count - 1) / 2])
    }
}

使用方法:

let array = [1,2,3,4,5,6,7,8]
let m2 = calculateMedian(array: array) // 4.5

使用 sorted 会导致算法花费 O(n log n) 的时间。如果性能很重要,最好选择一个在 O(n) 时间内完成的算法。 - Edward Brey

13

中位数被定义为序列中间的数字。如果没有一个中间数字,则是两个中间数字的平均值。

extension Array where Element == Int {
    func median() -> Double {
        let sortedArray = sorted()
        if count % 2 != 0 {
            return Double(sortedArray[count / 2])
        } else {
            return Double(sortedArray[count / 2] + sortedArray[count / 2 - 1]) / 2.0
        }
    }
}

6

请注意,如果数组为空,则中位数未定义。因此,安全的中位数函数会返回一个可选项,就像min()max()内置方法一样。

extension Array where Element == Int {
    func median() -> Double? {
        guard count > 0  else { return nil }

        let sortedArray = self.sorted()
        if count % 2 != 0 {
            return Double(sortedArray[count/2])
        } else {
            return Double(sortedArray[count/2] + sortedArray[count/2 - 1]) / 2.0
        }
    }
}

有了这个定义,你可以写出如下代码:

if let median = arr.median() {
    // do something
}

1
如果有人(像我一样)喜欢两行代码:

let sorted = arr.sorted(by: <)
let median = Double(sorted[arr.count/2] + sorted.reversed()[arr.count/2])/2.0

0

使用sorted的算法需要O(n log n)的时间。对于9个数字通常不是问题,但如果您的数组很大,请使用在O(n)时间内完成的算法。一个例子是这个k-th largest element algorithm。它递归地分割数组,但不必经过所有排序工作,因此速度更快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接