List Scala将分区划分为两个以上的列表

List Scala将分区划分为两个以上的列表,list,scala,List,Scala,我在Scala中有一个列表,我正试图根据一个涉及列表中多个元素的谓词将其划分为多个列表。例如,如果我有 a: List[String] = List("a", "ab", "b", "abc", "c") 我想得到b:List[List[String]这是一个List[String]的列表,这样内部List[String]==3的长度之和。i、 e列表(列表(“a”、“b”、“c”)、列表(“abc”)、列表(“ab”、“a”)、…) [编辑]对于长度为50或更短的列表需要花费合理的时间。构建

我在Scala中有一个列表,我正试图根据一个涉及列表中多个元素的谓词将其划分为多个列表。例如,如果我有

a: List[String] = List("a", "ab", "b", "abc", "c")
我想得到
b:List[List[String]
这是一个
List[String]
的列表,这样内部
List[String]==3的长度之和。i、 e
列表(列表(“a”、“b”、“c”)、列表(“abc”)、列表(“ab”、“a”)、…)


[编辑]对于长度为50或更短的列表需要花费合理的时间。

构建所有可能的子列表并筛选:

def filter[A](list: List[A])(predicate: (List[A] => Boolean)): List[List[A]] = {
  (for {i <- 1 to list.length
        subList <- list.combinations(i)
        if predicate(subList)
  } yield subList).toList
}

val a = List("a", "ab", "b", "abc", "c")

val result = filter(a)(_.foldLeft(0)(_ + _.length) == 3)
def filter[A](list:list[A])(谓词:(list[A]=>Boolean)):list[list[A]={

(对于{i来说,不可能构建比
O(2^n*O(p))更便宜的高效算法)
对于任何任意谓词,
p
。这是因为每个子集都必须求值。你永远不会得到对
n==50
有效的结果。我认为Sergey在这方面走得很好,但我们可以稍微优化他的代码。首先,我们可以注意到,如果字符串长度之和是n,那么当然,我们不需要检查由超过N个字符串组成的组合,因为最短的字符串至少有一个字符长。此外,我们可以不使用forsynctatic sugar,而使用sum方法,而不是更通用的方法(因此,可能不会那么快)foldLeft

为了清楚起见,让我们首先定义一个小辅助函数,它将计算字符串长度之和:

def sumOfStr(list: List[String]) = list.map(_.length).sum
现在主要的方法是:

def split(list: List[String], sum: Int) = 
  (1 to sum).map(list.combinations(_).filter(sumOfStr(_) == sum)).flatten.toList
编辑:结合我们的力量,我们为您提供了一个效率仍然很低的版本,但这是最佳的、合理的、我们可以做到的版本:

def sumOfStr(lst: List[String]) = {
  var sum = 0
  lst.foreach{ sum += _.length }
  sum  
}

def split(lst: List[String], sum: Int) = 
  (1 to sum).par
  .map(lst.combinations(_).filter(sumOfStr(_) == sum))
  .flatten.toList

抱歉,这对我来说效率太低了,速度太慢了。嗯。你没有定义任何性能要求。所以我真的不理解你的否决票。抱歉:)所以用性能要求或其他更新你的帖子。
list.view.map(u.length).sum
会更快。
.map
会导致构建一个新的列表,该列表会立即被丢弃。@nate,可能,但需要测量。
.view
也有开销。下面是一个显示时间差的快速而肮脏的测试。看起来时间不同,但平均而言
。view
比没有。
。迭代器
略快。查看
。展开它总是更快。我修改了基调,将字符串长度相加(这是一个常数时间操作,而不是
列表。长度
O(n)
).由于某种原因,
.iterator
始终比
.view
慢。谢谢,内特:)事实上,在我的电脑上,
view
iterator
快得多:3.0到3.8秒。而且不管怎样,
展开
胜过一切。