试图了解scanala在Scala中的树上

时间:2018-07-22 09:20:28

标签: scala

我正在Coursera的课程中,并且试图了解树上scanLeft的逻辑。 我们有以下代码:

在这里,我们将一棵树(没有中间值,仅在Leafs中具有值)作为输入,并返回一棵具有中间值(在节点中具有值)的树

 def upsweep[A](t: Tree[A], f: (A,A) => A): TreeRes[A] = t match {
      case Leaf(v) => LeafRes(v)
      case Node(l, r) => {
           val (tL, tR) = parallel(upsweep(l, f), upsweep(r, f))
           NodeRes(tL, f(tL.res, tR.res), tR)
      }
 }

下面给出给定具有中间值的树(节点中具有值)的代码,将返回没有中间值的树(a0是树t剩余的所有元素的约简)。

 def downsweep[A](t: TreeRes[A], a0: A, f : (A,A) => A): Tree[A] = t match {
      case LeafRes(a) => Leaf(f(a0, a))
      case NodeRes(l, _, r) => {
           val (tL, tR) = parallel(downsweep[A](l, a0, f),
           downsweep[A](r, f(a0, l.res), f))
      Node(tL, tR) } 
 }

最后是scanLeft代码:

 def scanLeft[A](t: Tree[A], a0: A, f: (A,A) => A): Tree[A] = {
      val tRes = upsweep(t, f)
      val scan1 = downsweep(tRes, a0, f)
      prepend(a0, scan1)
 }

我的问题是,为什么在向下扫描之前必须使用向上扫描方法? 使用upsweep,我们生成中间值,随后使用downsweep,我们“删除”(我们不需要使用)它们。

谢谢。

1 个答案:

答案 0 :(得分:1)

实际上更仔细地看这部分

case NodeRes(l, _, r) => {
       val (tL, tR) = parallel(downsweep[A](l, a0, f),
       downsweep[A](r, f(a0, l.res), f))

什么是l.res?我为什么建议必须要有它?(它是在向上扫描时创建的)我建议您一步一步地画在纸上,用(_ + _)这样的简单函数,该算法的作用是什么。如果您不了解此方法,也可以轻松地逐步解决并自行解决。

相关问题