rec*_*ant 9 functional-programming scala scala-collections
我有许多范围对象需要合并,以便所有重叠范围消失:
case class Range(from:Int, to:Int)
val rangelist = List(Range(3, 40), Range(1, 45), Range(2, 50), etc)
Run Code Online (Sandbox Code Playgroud)
这是范围:
3 40
1 45
2 50
70 75
75 90
80 85
100 200
Run Code Online (Sandbox Code Playgroud)
完成后我们会得到:
1 50
70 90
100 200
Run Code Online (Sandbox Code Playgroud)
命令式算法:
要做到这一点必须要创建大量的临时变量,索引循环等.
所以我想知道是否有更实用的方法?
乍一看,源集合必须能够像Stack一样提供pop()PLUS,能够在迭代时通过索引删除项目,但之后就不再那么具有功能了.
lee*_*777 11
我喜欢这些谜题:
case class Range(from:Int, to:Int) {
assert(from <= to)
/** Returns true if given Range is completely contained in this range */
def contains(rhs: Range) = from <= rhs.from && rhs.to <= to
/** Returns true if given value is contained in this range */
def contains(v: Int) = from <= v && v <= to
}
def collapse(rangelist: List[Range]) =
// sorting the list puts overlapping ranges adjacent to one another in the list
// foldLeft runs a function on successive elements. it's a great way to process
// a list when the results are not a 1:1 mapping.
rangelist.sortBy(_.from).foldLeft(List.empty[Range]) { (acc, r) =>
acc match {
case head :: tail if head.contains(r) =>
// r completely contained; drop it
head :: tail
case head :: tail if head.contains(r.from) =>
// partial overlap; expand head to include both head and r
Range(head.from, r.to) :: tail
case _ =>
// no overlap; prepend r to list
r :: acc
}
}
Run Code Online (Sandbox Code Playgroud)
Rex*_*err 11
尝试尾递归.(只有在没有发生尾递归优化的情况下才需要注释;如果可以注释,编译器将执行此操作.)
import annotation.{tailrec => tco}
@tco final def collapse(rs: List[Range], sep: List[Range] = Nil): List[Range] = rs match {
case x :: y :: rest =>
if (y.from > x.to) collapse(y :: rest, x :: sep)
else collapse( Range(x.from, x.to max y.to) :: rest, sep)
case _ =>
(rs ::: sep).reverse
}
def merge(rs: List[Range]): List[Range] = collapse(rs.sortBy(_.from))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2692 次 |
| 最近记录: |