用于Int和Long的Scala中位数函数

时间:2018-08-17 18:39:11

标签: scala generics numbers

我是scala语言的新手,并试图实现对Int和Long均适用的中值函数,这是我尝试做的事情:

 def getMedian[T: Numeric](seq: Seq[T]): T = {
      val sortedSeq = seq.sortWith(_ < _)
      if (seq.size % 2 == 1) sortedSeq(sortedSeq.size / 2)  else {
            val (up, down) = sortedSeq.splitAt(seq.size / 2)
            (up.last + down.head) / 2
       }
  }

,但比较运算符对数字类无效。我该怎么做。

1 个答案:

答案 0 :(得分:4)

结果类型有问题。如果将整数除以2,则结果不一定是整数。但是谁来决定结果的精度呢?应该是Double吗?还是Float足够近?

这是一个解决方案,您必须明确指定结果类型:

def getMedian[T: Ordering, F]
  (seq: Seq[T])
  (implicit conv: T => F, f: Fractional[F]): F = {
    val sortedSeq = seq.sorted
    if (seq.size % 2 == 1) sortedSeq(sortedSeq.size / 2)  else {
      val (up, down) = sortedSeq.splitAt(seq.size / 2)
      import f._
      (conv(up.last) + conv(down.head)) / fromInt(2)
    }
}

您现在可以按以下方式使用它:

println(getMedian[Int, Float](List(1,2,3,4)))
println(getMedian[Int, Double](List(1,2,3,4)))

它输出2.5两次,但第一个是单精度,而最后一个是双精度。

在使用时,您可以实现O(n) selection algorithm,例如quickselect,并使用T: Ordering来比较元素。这些算法都不依赖任何算术运算。