什么是最好的approch - 获取所有可能的子列表

时间:2018-01-24 06:48:07

标签: scala

我有一个List "a, b, c,d",这是预期的结果

a
ab
abc
abcd
b
bc
bcd
c
cd
d

我试过暴力,但我认为,如果我有很长的名单,可能还有其他有效的解决方案。

3 个答案:

答案 0 :(得分:2)

这是一个单行。

"abcd".tails.flatMap(_.inits.toSeq.init.reverse).mkString(",")
//res0: String = a,ab,abc,abcd,b,bc,bcd,c,cd,d

添加mkString()只是为了让我们看到结果。否则结果是Iterator[String],这是一种非常节省内存的集合类型。

reverse仅在那里,以便按照您指定的顺序出现。如果结果的顺序不重要,那么可以删除。

toSeq.init用于移除inits调用留下的空元素。如果这些可以在其他地方处理,那么这也可以删除。

答案 1 :(得分:1)

这可能不是最佳解决方案,但这样做的一种方法是使用sliding函数,如下所示,

val lst = List('a', 'b', 'c', 'd')

val groupedElements = (1 to lst.size).flatMap(x =>
      lst.sliding(x, 1))

groupedElements.foreach(x => println(x.mkString(""))) 

//output
  /*  a
      b
      c
      d
      ab
      bc
      cd
      abc
      bcd
      abcd
      */

答案 2 :(得分:0)

这可能不是最佳解决方案,但我认为这是一个很好的解决方案,而且是tailrec

首先使用此函数获取List

的可能子列表
 def getSubList[A](lista: Seq[A]): Seq[Seq[A]] = {
      for {
        i <- 1 to lista.length
      } yield lista.take(i)
  }

然后这个执行递归调用第一个函数并获得所有可能的子列表:

def getSubListRecursive[A](lista: Seq[A]): Seq[Seq[A]] = {
    @tailrec
    def go(acc: Seq[Seq[A]], rest: Seq[A]): Seq[Seq[A]] = {
      rest match {
        case Nil => acc
        case l => go(acc = acc ++ getSubList(l), rest= l.tail)
      }
    }
    go(Nil, lista)
  }

输出:

getSubListRecursive(l)


res4: Seq[Seq[String]] = List(List(a), List(a, b), List(a, b, c), List(a, b, c, d), List(b), List(b, c), List(b, c, d), List(c), List(c, d), List(d))
相关问题