Подсчитайте, сколько раз числа из списка встречаются в списке интервалов кортежей в Scala

1
задан Arun Shyam 18 January 2019 в 14:19
поделиться

2 ответа

Вот эффективное однопроходное решение:

ranges
  .map(r => r -> nums.count(n => n >= r._1 && n <= r._2))
  .toMap

Это позволяет избежать затрат на создание списка чисел, а затем объединить их с диапазонами на отдельном шаге.

Это версия, в которой используется больше функций Scala, но она слишком причудлива:

(for {
  r <- ranges
  range = r._1 to r._2
} yield r -> nums.count(range.contains)
).toMap

Это также менее эффективно, поскольку contains должен учитывать диапазоны со значением шага и, следовательно, более сложным.


А вот еще более эффективная версия, позволяющая избежать любых временных структур данных:

val result: Map[(Int, Int), Int] =
  ranges.map(r => r -> nums.count(n => n >= r._1 && n <= r._2))(collection.breakOut)

См. это объяснение breakOut , если вы не знакомы с ним , Использование breakOut означает, что вызов map будет создавать Map напрямую, а не создавать List, который должен быть преобразован в Map с использованием toMap.

0
ответ дан Tim 18 January 2019 в 14:19
поделиться

Примерно так:

val ranges = List((1, 4), (5, 8), (9, 10))
val nums = List(2, 2, 3, 7, 8, 9)

val occurences = ranges.map { case (l, r) => nums.count((l to r) contains _) }
val map = (ranges zip occurences).toMap

println(map) // Map((1,4) -> 3, (5,8) -> 2, (9,10) -> 1)

По сути, сначала вычисляется количество вхождений, [3, 2, 1]. Оттуда легко построить карту. И способ вычисления вхождений таков:

  • просмотреть список диапазонов
  • преобразовать каждый диапазон в число вхождений для этого диапазона, что делается следующим образом:
    • Сколько чисел из списка nums содержится в этом диапазоне?

РЕДАКТИРОВАТЬ: Не уверен, почему этот ответ получает отрицательный голос, возможно, я как-то неправильно понял вопрос .

0
ответ дан slouc 18 January 2019 в 14:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: