我遇到了这个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。我做错了什么?
答案 0 :(得分:2)
因此,您需要检查l1的every
元素是否为l2的member
。这些都是Common Lisp标准库中的函数,因此如果您允许使用它们,您可以使用它们构建一个简单的解决方案。
答案 1 :(得分:1)
为了能够同时处理两个列表,诀窍可能是在开始递归之前对列表进行排序。然后它应该是一个简单的事情,比较第一个元素,并递归地将相同的函数应用于列表的其余部分,当然添加了一些CAR / CDR魔法......
答案 2 :(得分:1)
不要试图在一个函数中执行所有操作,而是考虑将其拆分为两个(或更多)函数,例如
与DOLIST
一样,请考虑使用MAPCAR
和FIND-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))))
这是一个功能,确保a
是b
的一个子集(你问的是什么)
(defun subset (a b)
(same-elements (my-union a b) a))