Algorithm 如何优化从节点路径列表构建树?
假设我正在编写一个函数Algorithm 如何优化从节点路径列表构建树?,algorithm,scala,optimization,tree,Algorithm,Scala,Optimization,Tree,假设我正在编写一个函数fromPaths(path: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",
fromPaths(path: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
,然后将它折叠到列表上。但是,它看起来不太理想,因为对于路径
中的每个“路径”,我们将树从根
遍历到节点
如何优化遍历节点总数的
fromPaths
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")))
打印(直至缩进):
它不能以渐进的方式运行得更快,因为您必须至少查看输入的每个部分一次。显而易见的递归似乎工作得很好,至少在您的示例中是这样的:
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")))
打印(直至缩进):
它不能以渐进的方式运行得更快,因为您必须至少查看输入的每个部分一次。您到底尝试了什么,以及输入
“a”、“a/b/c”应该发生什么情况?您的结果树是否应该与“a”、“a/b”、“a/b/c”
(内部节点上没有标记?)
甚至没有任何有意义的打字检查?。而且所有的节点
构造函数都有错误的算术…再次:如果[“a/b”]
和[“a”,“a/b”]
的结果没有区别吗?哦,对不起。我的意思是节点(“a”,列表(节点(“b”),列表(节点(“c”))
您到底尝试了什么,输入“a”、“a/b/c”
会发生什么?生成的树是否与“a”、“a/b”、“a/b/c”
(内部节点上没有标记?)相同?对于“a”、“a/b/c”
,结果应该是节点(“a”、列表(节点(“b”)、列表(节点(“c”))
。我尝试了通过前缀对路径进行分组…List(Node(“b”)、List(Node(“c”))
甚至没有进行任何有意义的打字检查。而且所有的Node
构造函数都有错误的算术性…再次:对于[“a/b”]
和[“a”、“a/b”]的结果是否应该没有区别
?哦,对不起。我的意思是节点(“a”,列表(节点(“b”),列表(节点(“c”))