递归地比较两组的相等性?

时间:2011-05-16 19:59:05

标签: recursion scheme set racket equality

我对编程很新,我正在尝试构建一个函数,它将两个集合作为输入,可以包含其他集合(a(bc)de(fg(h)),(abc(def))例如,并返回它们是否相等。如果有帮助,我正在使用方案,但我真的想要想象我如何做到这一点。感谢您的帮助提前

3 个答案:

答案 0 :(得分:1)

一个简单的递归方法是选择集合A的元素并在集合B中查找相等的元素。如果找到一个,则从A和B中删除两个元素并递归。如果两个集合都为空,则停止成功;如果一个是空的,或者A中的选定元素在B中没有相应的元素,则停止失败。

答案 1 :(得分:0)

某些语言具有内置集类型,包括Racket。所以唯一的问题是将列表(可能包含其他列表)转换为嵌套集。所以像这样:(警告 - 完全未经测试的代码)

(require racket/set)
(define (recursive-make-set obj)
  (cond
    [(list? obj) (list->set (map recursive-make-set obj))]
    [else obj]))

基本上我们将原子单独留下,并使用递归转换的元素上的内置list->set函数构建一个列表集。

答案 2 :(得分:0)

两个关键点: (a)测试各个组件的匹配类型相同性 (b)当你到达“核心”元素值时测试匹配值

无论你使用哪种编程语言,如果我们查看一个列表,例如(a(bc)...)和(abc ...),我们会在看到“a”之后注意到每个是一个不同的类型。第一个列表在带有列表的“a”之后,而第二个列表跟在另一个非列表元素之后。语言可能会失败(表示某种错误)或者允许您类似地考虑这些不同的类型,但通常提供一种查询类型的方法。

在方案中(我不记得确切),第一个列表的汽车值为a,其cdr值为列表((b c)...)。第二个列表的汽车价值为a但cdr​​返回列表(b c ...)。除非语言提供不同的“相同性”视图,否则这两者不可能相同。

这种对象类型的测试将是查看列表是否相同的第一步。

接下来,我们测试已经验证的相同结构中相应位置的基本元素值。我们必须以正确的方式遍历结构(即,取决于结构细节)。

遍历的算法细节取决于编程语言。有些语言在避免错误和测试同一性方面提供了比其他语言更多的帮助。

我们可以使用递归或迭代方法。使用方案,从概念上讲,递归是更自然的。

样本伪代码,其中类型和值都由组合测试处理=?

function f (l1, l2):
(=? car(l1) car(l2))
and
(f cdr(l1) cdr(l2))

我们注意到递归。这样做的是,如果你得到一个简单的元素,它会测试eqality并返回该值。如果直接调用该函数,那么这是最终的答案,如果它是递归调用的,那么它将该答案发送回函数调用链,使得一些嵌套(f cdr(l1)cdr(l2))返回false或true并且最终使得最高级别的调用也返回false或者仍然能够返回true(注意“和”要求以及它是如何工作的。只有当每个部分都为真时才会出现true,而如果任何部分为假则会出现错误)。类似地,如果函数获得一个列表,那么它测试汽车部分并且“和”这个t / f值,当它在列表的其余部分上递归地再次调用它时获得它。因此,此函数处理您提供的子列表的任何复杂结构中的列表和非列表。 [记得,我们假设=?管理类型和值检查,例如,以便(=?b'(b))将是#f]

[另请参阅http://cs.gettysburg.edu/~tneller/cs341/scheme-intro/exercises.html#Equivalence了解可能用于测试等效性的内容。]