Scala 循环嵌套列表的函数方法

Scala 循环嵌套列表的函数方法,scala,functional-programming,tail-recursion,imperative-programming,Scala,Functional Programming,Tail Recursion,Imperative Programming,有人问我一个比较两棵树的问题。如下所示: 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]): Bo

有人问我一个比较两棵树的问题。如下所示:

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循环

考虑压缩这两个列表并使用
for all
,只有当它处理的每个谓词都计算为
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
时停止求值。通过定义填充长度差异的
EmptyNode
类,可以使用
zipAll
解决节点列表长度不相等的情况;此外,两个空列表可能与
true
相比较

更新
根据@JohnB的评论对节点列表进行排序以确保其合理性。

如果我正确理解了您的问题,您希望将第一个列表中的每个元素与第二个列表中的每个元素进行比较。下面的代码实现了这一点。它通过尾部递归摆脱
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
}

也许我误解了这个问题,但OP似乎想将第一个列表中的每个节点与第二个列表中的每个其他节点进行比较。您的代码无法实现这一点,对吗?使用zipAll和一个“emptynode”实例来填充任何缺失的案例,它将对它们进行比较。然而,我看到的问题是,如果它们具有相同的节点但不同的排序,则可以认为它们是相等的,所以先排序或将两个列表转换为SET,然后执行SET1.FALALL(C=>S2.包含(C))和逆。@ Junb同意,非常感谢这些评论。您可以对其他谓词使用
List.correcated
。顺便说一句,OP说孩子们是无序的,但这听起来不正常。(很抱歉,我看到了OP注释“完全相同的元素”,这不是一般的比较。)zip在我的情况下不起作用,我需要将外部列表中的每个元素与内部列表中的每个元素进行比较。在同一位置合并节点不起作用。是否需要将第一个列表中的每个元素与第二个列表中的每个元素进行比较?或者只是两个第一个元素,两个第二个元素等等?是的,我想比较两个无序的子元素,看看一个列表是否包含与另一个完全相同的元素,一直到叶节点。