【问题标题】:Use a recursive call in List.map在 List.map 中使用递归调用
【发布时间】:2012-09-24 00:44:35
【问题描述】:

我对 Scala 中的列表操作有疑问。我正在尝试实现相同的逻辑,我已经在 J​​ava 中按顺序实现了(并且它有效),但它返回了我没想到的 0。我已经尽可能地调试了列表操作(将提供的映射调用替换为列表序列,其行为符合预期),但我无法跟踪最后一步(将列表成员映射到此函数的递归调用)。你能提供一些关于我的方法的想法吗?

@tailrec
def a(b: Int, cList: List[Int]): Int = {
    if (b == 0) 1
    else if (cList.isEmpty) 0
    else
      List.range(0, b / cList.head).
        map(n => a(b - n * cList.head, cList.tail)). 
        foldLeft(0)((b, a) => b + a)
  }                                              

我想,在foldLeft 之前,列表必须包含对所有元素的递归调用的结果。这样的电话有效吗?为了清楚起见,我附上了我的 Java 程序,它的行为与假定的一样:

private static int a(int b, int[] cList) {
        if (b == 0) {
            return 1;
        } else {
            if (cList.length == 0)
                return 0;

            int head = cList[0];
            int[] tail = Arrays.copyOfRange(cList, 1, cList.length);
            int x = b / head;
            int sum = 0;
            for (int i = 0; i <= x; i++) {
                sum += a(b - (i * head), tail);
            }
            return sum;
        }
    }

【问题讨论】:

  • a是什么意思,算什么?顺便说一句,此类问题更多属于codereview.stackexchange.com
  • 哦,不知道有codereview网站会用它来解决这类问题。它计算使用给定硬币 cList(硬币类型)和数量 b 获得零钱的方法数量
  • 如果这是 countChange 问题,那你做得太过了。使用递归和模式匹配,解决方案要简单得多。没有必要折叠。见这里algorithmist.com/index.php/Coin_Change
  • 谢谢,如果这个问题有更简单的算法,那么我会在参考之前自己重新考虑一下。

标签: scala recursion


【解决方案1】:

查看 List.range 的文档:

价值为start, start + 1, ..., end - 1的$coll

补充说明:

  • 在您的情况下,尾调用优化不可用。
  • .foldLeft(0)((b, a) =&gt; b + a) 等于 .sum
  • 您将命令式循环解决方案与递归混合,尝试仅使用递归列表 处理

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 2016-08-07
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    相关资源
    最近更新 更多