获得最大尺寸列表的有效方法

时间:2014-04-10 15:19:23

标签: list scala scala-collections

我有一个scala List,其中包含一个字符串和一个整数列表。我想只过滤那些整数列表最大的那些。从最高和最低排序,然后取n个字符串的常用方法有一个缺点。

var qq = List[(String,List[Int])]()

比如说长度为10的List,有6个大小为65的列表,其余5个大小小于65.现在我需要从向量中检索所有6个列表。

方法:传统方式是对列表进行排序,获取最高列表的大小并添加具有该大小的过滤条件。

var max = qq.sortWith(_._2.size>_._2.size).head._2.size //get maximum size
var filList = qq.filter(p=>p._2.size>=max) //filter them

我的问题是在scala中还有其他快速有效的方法吗?正如我所做的那样,处理大约10,000-20,000次,列表大小更大。

2 个答案:

答案 0 :(得分:2)

对于性能,如果您只想要最大值,则不应对整个列表进行排序。

其次,在Scala中使用多线程代码非常容易:

  val data = List(("a", List(1, 2, 3)), ("b", List(4, 5)), ("c", List(45, 3, 2)))
  val maxListSize = data.par.map(_._2.size).max
  val largestLists = data.par.filter(_._2.size == maxListSize)
  println(largestLists)

只需添加.par(并行集合)即可实现多线程。请注意,除非您有非常大的列表,否则您可能希望删除这些.par,因为它们可能会减慢速度。对于大型列表,并行化将提供加速因子,即计算机上的核心数。

答案 1 :(得分:1)

我建议

val sorted = qq.sortBy(_._2.size)
val thresh = sorted.head._2.size  // assume qq is non-empty
val retain = sorted.takeWhile(_._2.size == thresh)

任何情况下的表现都受到排序程序的约束(当然比O(N)差)。


另一种方法是在不进行排序的情况下构建结果。只需跟踪最佳结果,并在检测到更大尺寸的列表时替换它们。

像这样:

type A = (String,List[Int])

((0, List.empty[A]) /: qq) { case (prev @ (bestLen, res), entry @ (_, list)) =>
  val eLen = list.size
  if      (eLen <  bestLen) prev
  else if (eLen == bestLen) (bestLen, entry :: res)
  else                      (eLen, entry :: Nil)
}

表现将是O(N),尽可能好。