我正在尝试编写一个函数来计算表示为元组的树的节点。
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中完成此操作?
答案 0 :(得分:8)
所以我会非常直白,并且给你的问题一个不实用但可能有趣的答案。绝对可以将二叉树表示为嵌套的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
具有正确的形状。对于任何其他类型的t
,count(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