获取数组的中位数

Get median of array

我有一个如下所示的数组:

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

我知道您可以通过以下方式获得 minmax

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

但是你如何得到中位数呢?

要获得 median,您可以使用以下方法:

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

在你的情况下它将 return 5.

正如@Nirav 指出的那样,[1,2,3,4,5,6,7,8] 将 return 5 但应该 return 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

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

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

请注意,如果数组为空,则中位数未定义。所以安全中值函数 returns 是可选的,就像 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
}

如果有人(像我一样)喜欢两个*衬里:

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

使用 sorted 的算法需要 O(log n) 时间。如果您实际上只有 9 个数字,那么性能损失并不显着。但是,如果您的数组很大,请使用在线性时间内完成的算法。一个例子是这个k-th largest element algorithm。它递归地对数组进行分区,但不必完成所有工作来对其进行排序,因此速度要快得多。