对于家庭作业问题,如果列表中的一部分位于另一个列表中,则必须删除列表中的重复项。预期结果应该是这样:
(remove-redundant '((R (1 2 3 8 e 4 7 6 5))
(U (e 2 3 1 8 4 7 6 5))
(D (1 2 3 7 8 4 e 6 5)))
'((D (1 2 3 e 8 4 7 6 5))
(L (e 2 3 1 8 4 7 6 5))
(U (2 e 3 1 8 4 7 6 5))
(U (2 8 3 1 e 4 7 6 5))))
返回:
((R (1 2 3 8 e 4 7 6 5)) (D (1 2 3 7 8 4 e 6 5)))
应该检查每个列表中的列表是否存在,因为第一个参数在第二个位置出现。如果确实出现,则将其从第一个列表中删除。基本上,如果(1 2 3 e 8 4 7 6 5)与第一个列表中的内容匹配,则将其从第一个列表中删除。我需要递归地执行此操作,它应该是一个功能程序。
我已经尝试过遍历该列表,但是不会重置(即它将检查第二个列表中第一个列表的开头,然后返回。
(defun same-state (l1 l2)
(if (equal (cadr l1) (cadr l2)) t nil))
(defun remove-redundant (l1 l2)
(cond
((null l2) l1)
((null l1) nil)
((same-state (car l1) (car l2)) (remove-redundant (cdr l1) (cdr l2))
(T (remove-redundant l1 (cdr l2)))))
答案 0 :(得分:1)
您已经接近,但是在t
表格的cond
情况下,您想要保留的单元格应该有一些堆积,
例如。
;; ...
(t
(cons (car l1) (remove-redundant (cdr l1) (cdr l2))))
,并且当您检查l1
中是否存在l2
的第一个元素时,应该进行另一个循环或递归来检查l2
中的所有元素,例如。
(defun same-state (l1 l2)
(find l1 l2 :key #'cadr :test #'equal))
(defun remove-redundant (l1 l2)
(cond
((null l2) l1)
((null l1) nil)
((same-state (cadar l1) l2)
(remove-redundant (cdr l1) (cdr l2)))
(t (cons (car l1)
(remove-redundant (cdr l1) (cdr l2))))))
;; => ((R (1 2 3 8 e 4 7 6 5)) (D (1 2 3 7 8 4 e 6 5)))
答案 1 :(得分:0)
您将需要两个循环:一个循环通过第一个列表,然后每个循环一个以在第二个列表中找到匹配项。