scala - Scala中的自定义组合函数
问题描述
我想在scala中实现一个组合功能,我的代码如下:
def combination[A](n: Int, ls: List[A]): List[List[A]] ={
(n, ls) match{
case (_, Nil) => List(Nil)
case (1, _) => ls.map(List(_))
case (_, _) if n > ls.size => List.empty
case _ => ls.flatMap(x => combination(n - 1, subList(x, ls)).map(x :: _))
}
}
def subList[A](e: A, in: List[A]) = in.takeRight(in.size - in.indexOf(e) - 1)
但结果不是我所期望的。当我打电话时combination(3, List('a, 'b, 'c, 'd, 'e, 'f)
。它会给我一个或两个元素的结果,比如 List('d, 'f), List('f) 等等。谁能帮我找到问题?谢谢。
更新:正确的版本是
def combination[A](n: Int, ls: List[A]): List[List[A]] ={
(n, ls) match{
case (_, Nil) => Nil
case (1, _) => ls.map(List(_))
case (_, _) if n > ls.size => Nil
case _ => ls.flatMap(x => combination(n - 1, subList(x, ls)).map(x :: _))
}
}
def subList[A](e: A, in: List[A]) = in.takeRight(in.size - in.indexOf(e) - 1)
解决方案
案例太多,不必要的combinations2
繁琐subList
。
回想一下组合是如何定义的。如果你有一个 set {a1, ..., aN}
,并且你想k
从这个 set 中选择元素,那么你基本上可以做两件事:
- 您不包含
a1
在子集中。然后你必须k
从剩余的{a2, ..., aN}
. - 您包含
a1
在子集中。然后你必须从中选择k-1
元素{a2, ..., aN}
,并添加a0
到这些k-1
元素中。
这就是公式
C(N, k) = C(N - 1, k) + C(N - 1, k - 1)
来自。
翻译成代码,这只是:
def comb[A](ls: List[A], k: Int): List[List[A]] = {
if (k == 0) List(Nil)
else ls match {
case Nil => List()
case h :: t => comb(t, k) ++ comb(t, k - 1).map(h :: _)
}
}
例子:
comb(List('a, 'b, 'c, 'd, 'e), 3) foreach println
给出:
List('c, 'd, 'e)
List('b, 'd, 'e)
List('b, 'c, 'e)
List('b, 'c, 'd)
List('a, 'd, 'e)
List('a, 'c, 'e)
List('a, 'c, 'd)
List('a, 'b, 'e)
List('a, 'b, 'd)
List('a, 'b, 'c)
推荐阅读
- php - 未执行数组中的循环
- batch-file - FNR.exe - 如何用计算机日期查找和替换整行
- django - 处理 url 编码数据时 django rest 框架出现问题
- python - 使用正则表达式的字符串数组上的 Numpy.where
- python - 错误的输入抛出了python
- javascript - 延迟后如何显示模式?
- delphi - delphi 发送邮件
- python - 运行 make 时无法识别 Python.h
- typescript - TypeError:尝试从firebase读取时无法读取未定义的属性'0'
- angular - 如何将 custum 属性添加到 Angular 8 中加载的 js 文件