1

我对 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;
        }
    }
4

1 回答 1

2

检查 List.range 的文档:

带有值的 $collstart, start + 1, ..., end - 1

补充说明:

  • 在您的情况下,尾调用优化不可用。
  • .foldLeft(0)((b, a) => b + a)等于.sum
  • 您将命令式循环解决方案与递归混合,尝试仅使用递归列表处理
于 2012-09-23T16:30:37.107 回答