如何在Common Lisp中创建等价函数?

时间:2017-05-30 16:21:51

标签: list lisp common-lisp

我知道可以使用" EQUAL"来检查2个列表是否具有相同的集合。 Common Lisp中的函数。

  

(等于'(a b c)'(a b c))=> Ť

     

(等于'(a b c)'(b c a))=> Ť

     

(等于'(a b c)'(d e f))=> NIL

但是你知道,如果两个列表以不同的顺序排列,那么这两个列表是不可能的。

我想有可能制作一个能够预测测试两个集合是否包含相同元素的函数,即使它们按照不同的顺序排列,使用' remove'函数和递归。但是,我的具体想法是完全具备这个功能。

我怎样才能实现这个想法?

2 个答案:

答案 0 :(得分:1)

可以找到完成此问题的解决方案here。该问题的OP有一个可行的解决方案,接受的答案是更好的解决方案。

我要做的是尝试解释逻辑。

让我们先解决这个问题。您已获得2个列表list1list2

  1. 如果list1为null,则如果list2也为null,则返回true。 (你不需要检查相反的情况,在步骤2中得到处理)
  2. 否则(list不为空/空):我们必须按照您的建议以某种方式删除两个集合中的元素。这可以通过 list3成为列表,以便list2移除list1中的第一项来实现。

    我。如果没有删除任何内容,即list2list3相等(这里可以使用普通equal),那么函数返回false,因为它在{{1}中找到了一个元素那不在list1

    II。如果删除了某些内容,请在list2)和list1的其余部分再次调用我们的函数。

答案 1 :(得分:1)

如果您想使用内置CL工具,可以使用set-exclusive-or,如下所示:

(defun sets-equivalent (set-a set-b)
  (not (set-exclusive-or set-a set-b)))

每个CLHS:

  

set-exclusive-或返回列表1和列表-2中恰好出现的元素列表。

因此,如果返回的列表为空,则表示集合是等效的。