根据最低编号范围将组编号分组

时间:2015-01-18 13:36:31

标签: scala

假设有数字列表和范围值,我想将它们分组,每组中的项目都在最低数字的范围内,并对它们进行排序。

例如,我有一个列表val l = List(1,2,3,4,5,6,7,8,9,10)和范围val range = 2。然后,我正在寻找输出以下结果的方法:result = List(List(1,2,3), List(4,5,6), List(7,8,9), List(10))。这意味着如果range = 0那么只有相同的数字在同一组中。

目前,我使用以下方法

val minVal = l.min
val range1 = (minVal + range).toDouble
val groups = l.foldLeft(Map[Int, List[Int]]())((result, num) => {
    val numRange = math.ceil(num / range1).toInt
    if (result.contains(numRange)) {
        result.updated(numRange, num :: result(numRange))
    } else {
        result.updated(numRange, List(num))
    }
})
groups.keys.toList.sortBy(k => k).map(groups(_))

除了range = 0slowestNum != 1之外,它适用于大多数情况。例如。对于列表val l = List(2,3,4,5,6,7,8,9,10)和范围val range = 2,结果为List(List(2), List(4, 3), List(6, 5), List(8, 7), List(10, 9))

所以,我想知道是否还有其他方法可以解决这个问题。

3 个答案:

答案 0 :(得分:6)

为何复杂化?

def coll(l: List[Int], range: Int): List[List[Int]] =
    if (l.isEmpty) Nil else {
        val (b, a) = l.span((l.head - range to l.head + range).contains)
        b :: coll(a, range)
    }

因此,该算法将数字收集到一个组中,直到数字在正/负范围内。

val list = List(7,4,1,9,10,20,50,52,30)
coll(list, 3)
res6: List[List[Int]] = List(List(7, 4), List(1), List(9, 10), List(20), List(50, 52), List(30))

如果您希望每个组自行排序,请拨打res6.map(_.sorted)

答案 1 :(得分:3)

我个人会这样做:

val l = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val range = 2

val result = l.sorted.foldLeft(List[List[Int]]()) {
  (cur, x) =>
    if ((cur nonEmpty) && x - cur.head.last <= range) (x :: cur.head) :: cur.tail
    else List(x) :: cur
}
虽然可能有一些聪明而巧妙的方法。当然,如果您想要订购结果,您总是可以这样做:

val ret = result.reverse.map(_.reverse)

希望它有所帮助!

答案 2 :(得分:1)

尝试这样的事情

val groupedList = l.map(i => l.filter(s => s >= i && s - i <= range))

groupedList.foldLeft(List(groupedList.head)) {
      case (r, c) => if (r.last.last < c.head) r ++ List(c) else r
 }             

对于范围2

val l = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val range = 2                                   
val groupedList = l.map(i => l.filter(s => s >= i && s - i <= range))
groupedList.foldLeft(List(groupedList.head)) {
case (r, c) => if (r.last.last < c.head) r ++ List(c) else r
}                                               
//> res0: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9), List(10))

对于范围0

 val l = List(1,1,1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
 val range = 0                                  
val groupedList = l.map(i => l.filter(s => s >= i && s - i <= range))
groupedList.foldLeft(List(groupedList.head)) {
case (r, c) => if (r.last.last < c.head) r ++ List(c) else r
}                                              
 //> res0: List[List[Int]] = List(List(1, 1, 1), List(2), List(3), List(4), List(5), List(6), List(7), List(8), List(9), List(10))