Как бы получить минимальный разрыв между элементами списка? - PullRequest
6 голосов
/ 11 ноября 2011

Например, предположим, у меня есть отсортированный список

val sorted = Список (1, 5, 15, 37, 39, 42, 50)

Наименьший разрыв составляет (39-37) = 2. Как бы я получил этот результат? Я смотрю на foldLeft, я чувствую, что это похоже на то, что мне нужно, но не совсем правильно

Ответы [ 5 ]

12 голосов
/ 11 ноября 2011
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)
3 голосов
/ 11 ноября 2011
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
1 голос
/ 11 ноября 2011

Использование 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
      )
    }
1 голос
/ 11 ноября 2011

Вот что я хотел бы сделать:

  1. написать функцию, которая преобразует список из n чисел в список (n - 1) пробелов

  2. написать / использовать функцию, которая выбирает наименьшее число из списка

Не забудьте обработать пустой список для части 1!(Кстати, часть 2 может быть написана в виде сгиба).

0 голосов
/ 11 ноября 2011

Обязательная (и, возможно, более быстрая) версия:

  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)
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...