Mar*_*ela 17 scala for-comprehension
给定一个数字与多个字符相关联的地图
scala> val conversion = Map("0" -> List("A", "B"), "1" -> List("C", "D"))
conversion: scala.collection.immutable.Map[java.lang.String,List[java.lang.String]] =
Map(0 -> List(A, B), 1 -> List(C, D))
Run Code Online (Sandbox Code Playgroud)
我想基于一系列数字生成所有可能的字符序列.例子:
"00" -> List("AA", "AB", "BA", "BB")
"01" -> List("AC", "AD", "BC", "BD")
Run Code Online (Sandbox Code Playgroud)
我可以用这些来理解
scala> val number = "011"
number: java.lang.String = 011
Run Code Online (Sandbox Code Playgroud)
为每个索引创建一系列可能的字符
scala> val values = number map { case c => conversion(c.toString) }
values: scala.collection.immutable.IndexedSeq[List[java.lang.String]] =
Vector(List(A, B), List(C, D), List(C, D))
Run Code Online (Sandbox Code Playgroud)
生成所有可能的字符序列
scala> for {
| a <- values(0)
| b <- values(1)
| c <- values(2)
| } yield a+b+c
res13: List[java.lang.String] = List(ACC, ACD, ADC, ADD, BCC, BCD, BDC, BDD)
Run Code Online (Sandbox Code Playgroud)
这里的东西变得丑陋,它只适用于三位数的序列.有没有办法在任何序列长度上获得相同的结果?
zig*_*tar 14
以下建议不使用理解.但我认为这毕竟不是一个好主意,因为你注意到你会被绑定到一定长度的笛卡尔积.
scala> def cartesianProduct[T](xss: List[List[T]]): List[List[T]] = xss match {
| case Nil => List(Nil)
| case h :: t => for(xh <- h; xt <- cartesianProduct(t)) yield xh :: xt
| }
cartesianProduct: [T](xss: List[List[T]])List[List[T]]
scala> val conversion = Map('0' -> List("A", "B"), '1' -> List("C", "D"))
conversion: scala.collection.immutable.Map[Char,List[java.lang.String]] = Map(0 -> List(A, B), 1 -> List(C, D))
scala> cartesianProduct("01".map(conversion).toList)
res9: List[List[java.lang.String]] = List(List(A, C), List(A, D), List(B, C), List(B, D))
Run Code Online (Sandbox Code Playgroud)
注意,上面的递归函数不是尾递归的.这不是问题,因为xss除非你有很多单身人士名单,否则会很短xss.情况就是这样,因为结果的大小随着非单例元素的数量呈指数增长xss.
我能想出这个:
val conversion = Map('0' -> Seq("A", "B"), '1' -> Seq("C", "D"))
def permut(str: Seq[Char]): Seq[String] = str match {
case Seq() => Seq.empty
case Seq(c) => conversion(c)
case Seq(head, tail @ _*) =>
val t = permut(tail)
conversion(head).flatMap(pre => t.map(pre + _))
}
permut("011")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14714 次 |
| 最近记录: |