假设我正在编写一个函数fromPaths(paths: List[String]): Node
,以从几个这样的节点路径构建树:
case class Node(value: String, children: List[Node])
val paths = List("a/b/x", "a/b/y", "a/c", "a/c/d")
fromPaths(paths) // Node("a", List(Node("b", List(Node("x"), Node("y"))), Node("c", List(Node("d")))))
我可以编写一个函数addNode(root: Node, path: String): Node
,然后将其fold
放在列表中。但是,由于我们针对root
中的每个“路径”将树从node
遍历到paths
,因此看起来不太理想。
您如何针对遍历的节点总数优化fromPaths
?
答案 0 :(得分:2)
至少在您的示例中,明显的递归似乎还不错:
case class Node[A](a: A, children: List[Node[A]])
def trieForest[A](lists: List[List[A]]): List[Node[A]] = {
lists.filter(_.nonEmpty).groupBy(_.head).map {
case (k, vs) =>
Node(k, trieForest(vs.map(_.tail)))
}.toList
}
def fromPaths(paths: List[String]): Node[String] = {
// assumes that there is only one tree in the
// top-level forest.
trieForest(paths.map(_.split("/").toList)).head
}
println(fromPaths(List("a/b/x", "a/b/y", "a/c", "a/c/d")))
打印(最多缩进):
Node(a, List(
Node(b,List(
Node(y,List()),
Node(x,List())
)),
Node(c,List(
Node(d,List())
))
))
它不能渐近运行,因为您必须至少一次查看输入的每个部分。