【问题标题】:Converting a tail-recursive merge function in Scala to a HOF-based one将 Scala 中的尾递归合并函数转换为基于 HOF 的合并函数
【发布时间】:2018-08-21 17:54:53
【问题描述】:

这是 Scala 中典型的尾递归合并函数(将用作示例,但我实际上正在寻找转换此类函数的一般答案):

  def merge(A: List[Int], B: List[Int]): List[Int] = {
    @tailrec def merge(A: List[Int], B: List[Int], acc: List[Int]): List[Int] = {
      (A, B) match {
        case (Nil, Nil) => acc.reverse
        case (Nil, h::t) => merge(Nil, t, h::acc)
        case (h::t, Nil) => merge(t, Nil, h::acc)
        case (a::ha, b::hb) =>
          if (a < b) merge(ha, b::hb, a::acc)
          else merge(a::ha, hb, b::acc)
      }
    }
    merge(A, B, Nil)
  }

我想知道通过使用 Scala 集合中的标准 HOF 是否可以避免必须实现递归函数。

似乎我总是必须从(A zip B) 之类的东西开始,但在那之后我真的不知道该走哪条路。有人可以帮忙吗?这只是一个没有价值的想法吗?

谢谢

【问题讨论】:

  • 在使用 zipAll 和默认值或 None 值后,可能会折叠结果集合?
  • 我对“一般答案”部分有点困惑。我们概括到什么程度?对于其他排序算法?还是一般的尾递归函数?很难说出这里的确切目的是什么......我的意思是,你总是可以做(a ++ b).sorted,但我怀疑你想通过使用另一个内置排序来实现合并排序。就压缩而言,你不能真正压缩,因为它可能是a 的前 n 个元素应该在 b 中的任何内容之前,所以成对压缩是没有用的。想想例如[1, 2, 3, 5][4, 6, 7, 8]... 压缩 (1, 4), (2, 6) 等不会让你走得太远。

标签: algorithm scala functional-programming


【解决方案1】:

据我了解,您正试图用一种结构递归替换此代码:

val merged = someNewDataStructure(A, B).fold(someFunction)

问题是在原始的尾递归调用中依赖于列表的一个值。

想象一下满足您要求的数据结构。 那么你遍历它的方式取决于你存储在那里的值。 即使有可能也是非常不自然的。

【讨论】:

    猜你喜欢
    • 2016-01-06
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多