等价类LISP

bub*_*ada 5 lisp class equivalence

我需要为等价类编写一个程序并获得此输出...

(equiv '((a b) (a c) (d e) (e f) (c g) (g h))) 
 => ((a b c g h) (d e f))

(equiv '((a b) (c d) (e f) (f g) (a e)))
 => ((a b e f g) (c d))
Run Code Online (Sandbox Code Playgroud)

基本上,A集是一个列表,其中顺序无关紧要,但元素不会出现多次.该函数应该接受对(这是根据一些等价关系相关的元素)的列表,并返回一组等价类,而无需使用迭代或赋值语句(如do,set!等).

然而,设置实用程序,如set-intersection,set-union和消除列表中的重复和内置函数的函数union,intersection以及remove-duplicates被允许的.

非常感谢!

顺便说一下,这不是一个家庭作业问题.我的一个朋友需要这段代码来解决微笑问题.

Rai*_*wig 4

这听起来像是一个典型的家庭作业问题。

不过,这并没有那么困难。

对输入列表进行简单的递归函数就可以了。该函数的组成部分已在任务描述中提到:简单的集合运算。

如果是家庭作业,则适用:家庭作业问题的典型策略是您必须首先展示您的解决方案尝试。这至少应该是算法的基本正确表述或几乎可以工作的代码。然后 Lispers 可能会帮助你完成最后的润色......

好吧,时间过去了,却没有解决办法。

下面是使用 Common Lisp 的一个:

我们需要三个函数。

第一个函数将单个对添加到对集中。一对是一个列表。对的集合是对的列表。对于该对,我们计算两个集合:等价对的集合和不等价对的集合。我们将与输入对等效的对组合成一个集合。

(defun equiv-add (e l)
  (let ((l- (remove-if     (lambda (i) (intersection e i)) l))
        (l+ (remove-if-not (lambda (i) (intersection e i)) l)))
    (cons (remove-duplicates (reduce #'union (cons e l+)))
          l-)))
Run Code Online (Sandbox Code Playgroud)

第二个函数将一组对中的每一对添加到结果中。它通过调用 EQUIV-ADD 添加它们。

(defun equiv-aux (list result)
  (if (null list)
      result
    (equiv-aux (rest list)
               (equiv-add (first list)
                          result))))
Run Code Online (Sandbox Code Playgroud)

第三个函数仅使用输入集和空结果调用 EQUIV-AUX。此外,它还会对结果子列表进行排序。

(defun equiv (list)
  (mapcar (lambda (el)
            (sort el #'string-lessp))
          (equiv-aux list '())))
Run Code Online (Sandbox Code Playgroud)

调用示例:

CL-USER 34 > (equiv '((a b) (c d) (e f) (f g) (a e)))
((A B E F G) (C D))

CL-USER 35 > (equiv '((a b) (a c) (d e) (e f) (c g) (g h))) 
((A B C G H) (D E F))
Run Code Online (Sandbox Code Playgroud)