如何获得List元素之间的最小差距?

时间:2011-11-11 01:44:46

标签: scala

例如,假设我有一个排序列表

val sorted = List(1,5,15,37,39,42,50)

最小间隙为(39-37)= 2。我怎样才能获得这个结果?我一直在看foldLeft我感觉它与我需要的相似,但不是很正确

5 个答案:

答案 0 :(得分:12)

val sorted = List(1, 5, 15, 37, 39, 42, 50)

sorted match { 
  case Nil => None
  case List(a) => None
  case l => Some(l.sliding(2).map{case Seq(a, b) => math.abs(a - b)}.min)
}
// res1: Option[Int] = Some(2)

sliding返回一个迭代器,因此只能遍历列表一次。

如果您有兴趣找到哪两个元素的间隙最小,您也可以使用minBy。所以这是另一种变化,只是为了好玩。

sorted.view.zip(sorted.tail).minBy(t => math.abs(t._1 - t._2))
// res4: (Int, Int) = (37,39)

答案 1 :(得分:3)

val sorted = List(1, 5, 15, 37, 39, 42, 50)
(sorted.tail,sorted).zipped.map(_-_).min
//res2: Int = 2

<强> [编辑]

您也可以使用折叠:

sorted.tail.foldLeft((sorted.head,Int.MaxValue))((x,y) => (y, math.min(y-x._1,x._2)))._2

答案 2 :(得分:1)

这就是我要做的事情:

  1. 编写一个将n个数字列表转换为(n - 1)个间隔列表的函数

  2. 编写/使用从列表中选择最小数字的函数

  3. 不要忘记处理第1部分的空列表案例! (顺便说一句,第2部分可以写成折叠)。

答案 3 :(得分:1)

使用foldLeft:

   sorted match {    
      case Nil | List(_) => None
      case x :: xs => Some(
        (xs.foldLeft((Integer.MAX_VALUE, x)) {
          case ((min, prev), next) => (math.min(min, next - prev), next)
        })._1
      )
    }

答案 4 :(得分:0)

命令式(可能更快)版本:

  if (sorted.isEmpty) {
    None
  } else {
    var sortedTail = sorted.tail
    if (sortedTail.isEmpty) {
      None
    } else {
      var minDiff = Int.MaxValue
      var prev = sorted.head
      do {
        val curr = sortedTail.head
        minDiff = minDiff min math.abs(curr - prev)
        sortedTail = sortedTail.tail
        prev = curr
      } while (!sortedTail.isEmpty)
      Some(minDiff)
    }
  }