我有一个问题来比较两棵树。如下所示:
case class Node(elem:String, child:List[Node])
为了比较树的每个元素,我有以下功能:
def compare(n1:Node, n2:Node): Boolean {
if(n1.elem == n2.elem){
return compare(n1.child, n2.child)
}
}
def compare(c1:List[Node], c2:List[Node]): Boolean {
while (c1.notEmpty) {
//filter, map etc call function above to compare the element recursively
}
}
基本上算法是针对n1中的每个元素,我们正在检查n2中的匹配。我被告知这是非常必要的方式而不是功能方式。什么是实现这种行为的功能性方法。换句话说,在比较孩子列表时,我们如何删除while循环?
答案 0 :(得分:4)
考虑压缩两个列表并使用forall
仅在其处理的每个谓词的计算结果为true
时才使用true
;比如像这样,
def compare(c1: List[Node], c2: List[Node]): Boolean =
(c1.sorted zip c2.sorted).forall(c => compare(c._1,c._2))
请注意forall
会在遇到第一个false
时暂停评估。通过为填充长度差异定义zipAll
类,可以使用EmptyNode
来处理不等长节点列表的情况;这两个列表都可以与true
进行比较。
<强>更新强> @JohnB评论后的健全性节点列表。
答案 1 :(得分:2)
如果我正确理解了您的问题,您希望将第一个列表的每个元素与第二个列表的每个元素进行比较。以下代码实现了这一点。它通过尾递归摆脱了while
循环。
import scala.annotation.tailrec
def cmp(a:Int, b:Int) = a > b
@tailrec
def compare(xs: List[Int], ys: List[Int]): Boolean = xs match {
case Nil => true
case head :: tail if ys.forall(x => cmp(head, x)) => compare(tail, ys)
case _ => false
}