Lisp - lisp的元素出现在其他列表中

时间:2011-12-03 00:08:58

标签: lisp

我遇到了这个lisp函数的问题。我想创建一个接收两个列表的函数,并验证第一个列表中的元素(所有这些元素)是否出现在第二个列表中,如果发生这种情况,它将返回True。

目前我有以下代码:

(defun ocorre-listas (l1 l2)
(dolist (elem1 l1)
    (dolist (elem2 l2)
        (if (equal elem1 elem2)
            t))))

按预期,它无法正常工作。我应该尝试通过简单的递归来做到这一点吗?我真的没有得到如何迭代两个列表来寻找相同的元素。

我决定尝试没有白话人。这就是我现在所拥有的,它仍然没有用。

(defun ocorre-listas (l1 l2)
(cond ((null l1) nil)
        ((null l2) nil)
        ((if (/= (first l1)(first l2)) (ocorre-listas l1 (rest l2))))
        (t (if (= (first l1) (first l2)) (ocorre-listas (rest l1)(rest l2))))))

我收到警告说“t”是一个未定义的函数。此外,我尝试的每个示例都返回null。我做错了什么?

6 个答案:

答案 0 :(得分:2)

因此,您需要检查l1的every元素是否为l2的member。这些都是Common Lisp标准库中的函数,因此如果您允许使用它们,您可以使用它们构建一个简单的解决方案。

答案 1 :(得分:1)

为了能够同时处理两个列表,诀窍可能是在开始递归之前对列表进行排序。然后它应该是一个简单的事情,比较第一个元素,并递归地将相同的函数应用于列表的其余部分,当然添加了一些CAR / CDR魔法......

答案 2 :(得分:1)

不要试图在一个函数中执行所有操作,而是考虑将其拆分为两个(或更多)函数,例如

  • 取一个数字和第二个列表,并测试该数字是否出现在列表中
  • 另一个迭代第一个列表中的数字,并且每个测试(使用第一个函数)是否出现在第二个列表中。

DOLIST一样,请考虑使用MAPCARFIND-IF(假设此作业允许使用{。}}。

答案 3 :(得分:1)

在第二段代码中,如果第一个列表为空,则其所有元素都在第二个列表中。

由于您位于ifs

内,因此您不需要cond

测试后列表是否为空,您只需要测试第一个列表的第一个元素是否在第二个列表中,并使用没有此元素的第一个列表再次调用该函数

答案 4 :(得分:1)

查看常见的lisp subsetp 谓词及其实现:

CL-USER> (subsetp '(1 2 3) '(1 2 3 4)
T

答案 5 :(得分:0)

虽然有很多方法可以做到这一点,但我建议使用哈希表来避免O(n^2)复杂性。使用哈希表,您可以实现O(n)复杂度。

这是一个联合函数

(defun my-union (a b)
  (let ((h (make-hash-table :test #'equal)))
    (mapcar (lambda (x) (setf (gethash x h) x)) a)
    (mapcan (lambda (x) (when (gethash x h) (list x))) b)))

这是两个列表中的IDENTICAL元素的功能测试

(defun same-elements (a b)
  (apply #'= (mapcar #'length (list (my-union a b) a b))))

这是一个功能,确保ab的一个子集(你问的是什么)

(defun subset (a b)
  (same-elements (my-union a b) a))