【问题标题】:All permutations with repetition using scala使用scala重复的所有排列
【发布时间】:2011-09-19 17:15:04
【问题描述】:

我正在寻找一种 scala 方式来给出所有排列而不重复。我知道这个网站上已经有一些帖子,但他们似乎有一个稍微不同的问题。

我正在寻找所有重复的排列。 例如:

combine(List('A','C','G'))

应该让步:

List(List('A'.'A','A'),List('A'.'A','C'),List('A'.'A','G'),List('A'.'C','A'),
List('A'.'C',''C), ... List('G'.'G','G')

如果我的问题已经解决但我找不到它,我很抱歉。

提前致谢。

编辑:

我自己的方法(不编译):

def combine(size: Int = sym.length) : List[List[T]] = {
  size match {
    case 0 => List()
    case 1 => sym.toList.map(List(_))
    case _ => for (el <- sym) yield el :: combine(size-1)
  }
}

sym 是一个类的数组成员,其中包含要组合的所有符号。

【问题讨论】:

  • 这描述了输入列表的所有组合的所有排列的列表
  • 不,它描述了所有重复排列

标签: scala combinations combinatorics repeat


【解决方案1】:

使用 Scalaz:

scala> import scalaz._
import scalaz._

scala> import Scalaz._
import Scalaz._

scala> def combine[A](xs: List[A]): List[List[A]] = {
     |   xs.replicate[List](xs.size).sequence
     | }
combine: [A](xs: List[A])List[List[A]]

scala> combine(List('A', 'C', 'G'))
res47: List[List[Char]] = List(List(A, A, A), List(A, A, C), List(A, A, G), List
(A, C, A), List(A, C, C), List(A, C, G), List(A, G, A), List(A, G, C), List(A, G
, G), List(C, A, A), List(C, A, C), List(C, A, G), List(C, C, A), List(C, C, C),
 List(C, C, G), List(C, G, A), List(C, G, C), List(C, G, G), List(G, A, A), List
(G, A, C), List(G, A, G), List(G, C, A), List(G, C, C), List(G, C, G), List(G, G
, A), List(G, G, C), List(G, G, G))

【讨论】:

  • 这在 Haskell 中更可爱:combine = sequence . (replicate =&lt;&lt; length).
  • 这似乎不再适用于最新版本的 Scalaz。看来库中只有replicateM(n: Int) 方法,但没有replicate[List](n: Int) 方法。
  • @WilliamDeMeo,这个答案是六年前写的。 Scalaz 中的一切都不再相同了。
  • 是的,我明白了……仍然值得指出,你不觉得吗? ...所以人们不会浪费时间尝试这个解决方案吗?也许您会考虑更新您的解决方案,以便它仍然有用。
  • @WilliamDeMeo,唉,这些天我不再有那种时间了。 :) 但请随时根据新版本进行更新!
【解决方案2】:
def combinations(size: Int = sym.length) : List[List[T]] = {
    if (size == 0)
        List(List())
    else {
        for {
            x  <- sym.toList
            xs <- combinations(size-1)
        } yield x :: xs
    }
}

【讨论】:

    【解决方案3】:

    这应该有效:

    val input = List('A','C','G')
    
    (input ++ input ++ input) combinations(3) toList
    

    【讨论】:

    • +1 或者当你不知道原始列表的大小时:(input.map(_ =&gt; input)).flatten.combinations(3).toList
    • @opyate 不错 :)。它甚至可以缩短为input.flatMap(_ =&gt; input).combinations(3).toList。我最接近的不同的不太好的方法是Seq.fill(input.size)(input).flatten.combinations(3).toList
    • 这与 OP 的规范不符。例如,您的结果将包括List('A', 'A', 'C'),这是应该的,但它不会包括List('A', 'C', 'A'),也不包括List('C', 'A', 'A')。 OP 想要所有三元素列表,其中每个列表中元素的顺序很重要。
    • 换句话说,OP 要求的是排列,而不仅仅是组合。
    【解决方案4】:
    scala> def comb(s:String)=(s * s.length).combinations(s.length)
    comb: (s: String)Iterator[String]
    
    scala> comb("ACG").toList
    res16: List[String] = List(AAA, AAC, AAG, ACC, ACG, AGG, CCC, CCG, CGG, GGG)
    

    如果你想要得到的排列:

    scala> comb("ACG").flatMap(_.toSeq.permutations.toList).toList
    res11: List[Seq[Char]] = List(AAA, AAC, ACA, CAA, AAG, AGA, GAA, ACC, CAC, CCA, ACG, AGC, CAG, CGA, GAC, GCA, AGG, GAG, GGA, CCC, CCG, CGC, GCC, CGG, GCG, GGC, GGG)
    

    您可以省略toList,但它在那里,因此您可以看到结果。

    【讨论】:

    • ACA 与 AAC 是相同的组合。它是一个不同的排列
    • 啊,是的。我只是在阅读 OP 的示例,其中包括 AAC 和 ACA,而不是他实际要求的内容。我的错。
    • 是的,很明显,OP 可能想要排列。我会将其添加到我的答案中。
    【解决方案5】:

    似乎没有人提出最简单的——或者至少是最容易阅读的——解决方案。这是

    myList = List("A", "C", "G")
    for {
      i <- myList
      j <- myList
      k <- myList
    } yield List(i,j,k)
    

    (这是以下地图组合的语法糖:

    myList.flatMap(i => myList.flatMap(j => myList.map(k => List(i,j,k))))
    

    Scala 编译器将上述for 表达式翻译成它。)

    【讨论】:

      【解决方案6】:

      在 ScalaZ 7 中

      import scalaz._
      import Scalaz._
      def combinine[T](l: List[T]) = l.replicateM(l.size)
      

      【讨论】:

        【解决方案7】:

        只是从@opyate 和@monnef 提出更通用的答案:

        // considering that we want a permutation_size
        List.fill(permutation_size)(input).flatten.combinations(permutation_size).toList
        

        这将生成具有重复大小 permutation_size 的排列:

        val a = List.fill(2)(List("A","B","C")).flatten.combinations(2).toList
        a: List[List[String]] = List(List(A, A), List(A, B), List(A, C), List(B, B), List(B, C), List(C, C))
        

        val a = List.fill(3)(List("A","B","C")).flatten.combinations(3).toList
        a: List[List[String]] = List(List(A, A, A), List(A, A, B), List(A, A, C), List(A, B, B), List(A, B, C), List(A, C, C), List(B, B, B), List(B, B, C), List(B, C, C), List(C, C, C))
        

        【讨论】:

        • 这不是解决方案。您的结果与 OP 的规范不符。请注意,您不会有条目 List(A, C, A),但 OP 希望将其包含在结果中。
        猜你喜欢
        • 2013-02-15
        • 1970-01-01
        • 2018-09-29
        • 1970-01-01
        • 2019-06-03
        • 1970-01-01
        • 2022-09-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多