我想修复自己的函数,它使用默认的交集函数给出相同的结果。我一直在尝试编写一个lisp代码,在两个列表中打印相同的元素。我的代码适用于它。但它不适用于嵌套列表。我怎样才能解决这个问题?
(defun printelems (L1 L2)
(cond
((null L1) nil) ((member (first L1) L2) (cons (first L1) (printelems (rest L1) L2)))
(t (printelems (rest L1) L2))))
预期的投入和产出
(printelems '(2 3 5 7) '( 2 3)) => It works
=> (2 3)
(printelems '(a b '(c f)) '(a d '(c f) e)) => It doesn't work.
=> (a (c f))
使用默认交叉功能按预期工作。如何在递归函数中使用相等的函数?
对于默认交叉点,
(intersection '(a b (c f)) '(a d (c f) e) :test 'equal)
((C F) A)
(intersection '(a b (c f)) '(a d c f e) :test 'equal)
(A)
我的路口,
(printelems '(a b (c f)) '(a d c f e))
(A C F)
(printelems '(a b (c f)) '(a d (c f) e) )
(A C F)
我编辑的代码:
(defun flatten (l)
(cond ((null l) nil)
((atom (car l)) (cons (car l) (flatten (cdr l))))
(t (append (flatten (car l)) (flatten (cdr l))))))
(defun printelemsv1(list1 list2)
(cond
((null list1) nil)
(((member (first list1) list2) (cons (first list1) (printelemsv1 (rest list1) list2)))
(t (printelemsv1 (rest list1) list2)))))
(defun printelems (L1 L2)
(printelemsv1 (flatten L1) (flatten L2)))
答案 0 :(得分:1)
Common Lisp已经有一个 intersection 功能。如果您想比较(CF)等子列表,则您希望使用等于或 equalp 作为测试参数。
(intersection '(a b '(c f)) '(a d '(c f) e) :test 'equal)
;=> ('(C F) A)
虽然它不会改变交叉点的工作方式,但您可能不希望在列表中引用。 引用不是列表创建运算符;它是一个"返回读者阅读的内容"运营商。读者可以读取(ab(cf))作为两个符号和子列表的列表,所以(引用(ab(cf))),通常缩写为'(ab(cf))很好。 E.g:
(intersection '(a b (c f)) '(a d (c f) e) :test 'equal)
;=> ((C F) A)
答案 1 :(得分:0)
当您提供输入和预期输出的示例时,它总是有用的。我假设您的意思是您有两个列表,例如'(1 (2 3) 4)
和'((1) 2 5 6)
,该函数应该生成'(1 2)
。在这种情况下,您可以在将两个列表提交给printelems
之前展平它们。
由于我不熟悉Common-Lisp本身,我会给你一个例子和一个链接。
(defun flatten (structure)
(cond ((null structure) nil)
((atom structure) (list structure))
(t (mapcan #'flatten structure))))
flatten
采用任意s表达式,如嵌套列表'(1 (2 3) 4)
,并返回'(1 2 3 4)
。
所以现在你只需编写一个新函数,在其中使用printelems
作为辅助函数并为其提供展平列表。
(defun printelems.v2 (L1 L2)
(printelems (flatten L1) (flatten L2)))
请注意这一点,因为如前所述,我不熟悉Common-Lisp,所以请提前预测任何潜在的语法错误。