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

Lisp-Lisp的元素出现在其他列表中,lisp,Lisp,我对这个lisp函数有问题。我想创建一个函数,它接收两个列表,并验证第一个列表中的元素(全部)是否出现在第二个列表中,如果出现这种情况,它将返回True 目前我有以下代码: (defun ocorre-listas (l1 l2) (dolist (elem1 l1) (dolist (elem2 l2) (if (equal elem1 elem2) t)))) 它不起作用,正如预期的那样。我应该试着用一个简单的递归来实现它吗?我真的不明白如何

我对这个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。我做错了什么?

为了能够同时处理两个列表,诀窍可能是在开始递归之前对列表进行排序。然后,它应该是一个简单的事情,比较第一个元素,并将相同的函数递归地应用到列表的其余部分,当然也有一些CAR/CDR魔法添加……/P>< P>,而不是试图在一个函数中做所有的事情,而是把它拆分为两个(或更多)函数,例如

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

以及<代码> DOLIST ,考虑使用<代码> MAPCAR < /COD>和<代码> FID-IF < /COD>(假设它们被允许在这个赋值中)

< P>在第二段代码中,如果第一个列表是空的,那么它的所有元素都在第二个代码中。 您不需要
ifs
,因为您在
cond


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

,因此您需要检查l1的
每个
元素是否都是l2的
成员。这两个函数都是公共Lisp标准库中的函数,因此如果允许您使用它们,您可以使用它们构建简单的解决方案。

请参阅公共Lisp标准库 谓词及其实现:

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

虽然有很多方法可以做到这一点,但我建议使用哈希表来避免复杂性。使用哈希表,可以实现
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)))
下面是两个列表中相同元素的函数测试

(defun same-elements (a b)
  (apply #'= (mapcar #'length (list (my-union a b) a b))))
这是一个函数,用于确保
a
b
的子集(您所要求的)


列表已排序。。。最困难的部分是让汽车/CDR魔术般地发生;)正确缩进代码。请确保表单嵌套正确。注意:我的函数假定列表不包含重复项
(defun subset (a b)
  (same-elements (my-union a b) a))