整数2..12:
的素数因子列表[List [Int]]List(List(2), List(3), List(2, 2), List(5), List(3, 2),
List(7), List(2, 2, 2), List(3, 3), List(5, 2),
List(11), List(3, 2, 2))
需要将其展平,以使得结果数据结构仅包含每个素数的最长序列(最大功率):
List(2,2,2,3,3,5,7,11)
例如,除了两个最强大的力量之外的所有力量:
列表(列表( 2 ),List(3),List( 2,2 ),List(5),List(3 ,2 )
列表(7),列表( 2,2,2 ),列表(3,3),列表(5 ,2 ),
列表(11),列表(3 ,2,2 ))
在初始列表中,素数的子列表总是按降序排序。
努力寻找一种优雅的,最好是≤O(n)的解决方案。
我的解决方案远非理想:
xs.flatMap(l=> l.groupBy(x=>x)).map(x=>(x._1,x._2.length)).
groupBy(_._1).mapValues(_.maxBy(_._2)).values.
map(x=>List.fill(x._2) (x._1)).flatten
答案 0 :(得分:1)
这比你的要短得多;它在概念上足够接近我希望你能弄明白:
xs.flatMap(_.groupBy(x=>x)).groupBy(_._1).
flatMap(_._2.sortBy(- _._2.length).head._2).toSeq.sorted
答案 1 :(得分:1)
经过一些分析后,问题归结为两个排序列表的简单合并,但略有不同 - 它必须只添加一次重复元素:
merge(List(5,3,3,2),List(7,5,3,2,2)
必须产生:
List(7,5,3,3,2,2)
一旦有了这样精彩的merge
功能,列表清单就可以从左到右简单地减少。
解决方案
def merge (xs:List[Int],ys:List[Int]):List[Int] = (xs,ys) match{
case (Nil,_) => ys
case (_,Nil) => xs
case (x::xxs,y::yys) => if (x==y) x::merge(xxs,yys)
else if (x>y) x::merge(xxs,ys)
else y::merge(xs,yys)
}
// note the simplicity of application
ll reduce merge
尾递归版merge
- 避免长列表上的堆栈溢出:
def merge (xs:List[Int],ys:List[Int]) = {
def m (rs:List[Int],xs:List[Int],ys:List[Int]):List[Int] = (xs,ys) match {
case (Nil,_) => ys reverse_:::rs
case (_,Nil) => xs reverse_:::rs
case (x::xxs,y::yys) => if (x==y) m(x::rs,xxs,yys)
else if (x>y) m(x::rs,xxs,ys)
else m(y::rs,xs,yys)
}
m(Nil,xs,ys).reverse
}
merge
的更快命令版本:
def merge (x:List[Int],y:List[Int]) = {
var rs = new scala.collection.mutable.ListBuffer[Int]()
var xs = x
var ys = y
while(!xs.isEmpty && !ys.isEmpty) {
if (xs.head>ys.head) {
rs+=xs.head
xs=xs.tail
} else if(xs.head==ys.head) {
rs+=xs.head
xs=xs.tail
ys=ys.tail
} else {
rs+=ys.head
ys=ys.tail
}
}
rs ++= xs ++= ys toList
}
答案 2 :(得分:0)
val ll = List(List(2), List(3), List(2, 2), List(5), List(3, 2),
List(7), List(2, 2, 2), List(3, 3), List(5, 2),
List(11), List(3, 2, 2))
val s = ll.flatten toSet
s.map (n => ll.map (l => (n, l.count (_ == n)))).map (l => (l(0) /: l.tail) ((a, b) => if (a._2 > b._2) a else b))
产生
scala.collection.immutable.Set[(Int, Int)] = Set((7,1), (11,1), (2,3), (5,1), (3,2))
扩展因子并对它们进行排序,生成List(2,2,2,3,3,5,7,11)留作练习。