我有两个树(路径),由类似
的节点定义trait Node {
def getParent : Node
def op(n:Node)
}
我希望向上移动两个节点,直到父级并行为null,如:
伪:
def simultanousUp(/*var*/ a:Node,/*var*/ b:Node) =
while(a != null) {
a.op(b);
a = a.getParent;
b = if(b!=null) b.getParent else null /*or throw somthing*/;
}
问题:在scala中有更优雅和/或高效的方法吗?
为避免误解:这不是关于并发执行的问题!
答案 0 :(得分:3)
父级不能为空。
首先,我们是正确的:
trait Node {
def parent : Option[Node]
def op(n:Node) // what does op mean ? what is the return type of op ?
//cannot be Unit
}
然后
@scala.annotation.tailrec
//it makes sure it's tailrec, so it can be optimized
def simultanousUp(a:Node, b:Node): (Node,Node) = {
a.op(b)
(a.parent, b.parent) match {
case (Some(pa), Some(pb)) => simultanousUp(pa,pb)
case _ => (a,b)
}
}
答案 1 :(得分:3)
@annotation.tailrec final def simultaneousUp(a: Node, b: Node) {
if (a != null && b != null) {
a op b
simultaneousUp(a.getParent, b.getParent)
}
// Throw exception or whatever on mismatched lengths?
}
答案 2 :(得分:-1)
如果op是一个简单的操作,则无法有效地并行运行,因为遍历会占用大量时间。
如果op是一个更复杂(即耗时)的操作,您可以并行执行。但是,您需要先将其转换为ParVector或类似的东西。
我认为没有更高效的遍历方式。然而,Stream有一个更优雅(但可能不那么高效)的解决方案:
def pathTo(start: Node): Stream[Node] = start.getParent match{
case null => Stream.empty
case nextPoint => Stream.cons(start, pathTo(nextPoint))
}