树在scala中表示为元组

时间:2014-05-23 01:20:22

标签: scala tuples binary-tree

我正在尝试编写一个函数来计算表示为元组的树的节点。

object Main {
     def count[T](tree:Seq[T]):Int= {
        if (lst == ())
            0
        else
            count(tree(1)) + count(tree(2)) + 1
    }
     def main(args: Array[String]) {
        val lst3 = (2,(6,(8,(),()),(5,(),())),(4,(3,(),()),(10,(),())))
        println(count(lst3))
    }
}

如何在scala中完成此操作?

2 个答案:

答案 0 :(得分:8)

丹的答案在实际意义上是正确的答案(而且我刚刚相应地进行了投票),但在另一种意义上,你的直觉是完全正确的:你已经选择了什么是优秀的在Scala中表示二叉树的方法 - 如果只有代数数据类型(如Dan的答案)那就更好了。

所以我会非常直白,并且给你的问题一个不实用但可能有趣的答案。绝对可以将二叉树表示为嵌套的3元组,并且还可以编写100%类型安全的count函数来计算这样一棵树中的所有节点:

trait Counter[T] { def count: Int }

object Counter {
  implicit object UnitCounter extends Counter[Unit] {
    val count = 0
  }

  implicit def branchCounter[A, L, R](implicit
    lc: Counter[L],
    rc: Counter[R]
  ): Counter[(A, L, R)] = new Counter[(A, L, R)] {
    def count = 1 + lc.count + rc.count
  }
}

def count[T](t: T)(implicit c: Counter[T]) = c.count

我们已经定义了类型类 Counter,它告诉我们某些类型T中有多少个节点。我们已经非常谨慎地选择了我们定义的类型实例,因此编译器无法为任何旧的T提供实例-just T具有正确的形状。对于任何其他类型的tcount(t)不会编译。

我们可以尝试一下:

val lst3 = (2, (6, (8, (), ()), (5, (), ())), (4, (3, (), ()), (10, (), ())))

然后:

scala> count(lst3)
res0: Int = 7

可是:

scala> count("foo")
<console>:11: error: could not find implicit value for parameter c: Counter[String]
              count("foo")
                   ^

请注意,这在编译时是错误的 - 我们没有放弃任何类型安全。

再说一遍:出于任何实际目的,你应该在另一个答案中使用这种方法,但你没有想到的那么错误。

答案 1 :(得分:6)

这不是使用元组的正确方法。 Scala是一种静态类型语言,因此不应将元组用作任意对象的通用容器。

树应该用以下类来表示:

trait Tree { def value: Int }
case class Branch(value: Int, children: Seq[Tree]) extends Tree
case class Leaf(value: Int) extends Tree

然后你可以这样做:

def count(t: Tree): Int = t match {
  case Branch(v, children) => 1 + children.map(count).sum
  case Leaf(v) => 1
}

所以:

val x = Branch(7, Seq(Branch(8, Seq(Leaf(1), Leaf(2))), Leaf(3)))
count(x)  // 5