使用Common Lisp删除多级列表中的重复项

时间:2014-03-27 21:40:21

标签: list duplicates lisp common-lisp multi-level

删除MULTI-LEVEL列表中的重复项(使用Common Lisp)而不更改列表的内部结构。这个问题对我来说似乎是一个难题,也是一个令人头痛的问题。

来源清单: (1 2(6 5)2 3(5 4))==>结果:(1(6)2 3(5 4))

这是我未做出的决定:

LispWokrs:

(defun F(l& optional(lst(remove-duplicates(flatten l))))

(cond
    ((null l) nil)

    ((atom (car l))

        (if (member (car l) lst)
            (cons (car l) (F (cdr l) (remove (car l) lst)))
            (F (cdr l) lst)))

    (t (cons (F (car l) lst) (F (cdr l) lst)))))

我尝试使用lst来保持一个清晰的集合(1 2 6 5 3 4),并且每次添加新元素时我都试图从该集合中删除元素。 但我得到的几乎是相同的源序列(并行递归......):

(f'(1 2(6 5)2 3(5 4)))==> (1 2(6 5)3(5 4))

(f'(А((B C E)D(B E A))))==> (А((B C E)D(B E A)))

然后我在网上搜索,但没有决定这个问题。

1 个答案:

答案 0 :(得分:1)

试试这个:

(defun multi-level-list-remove-duplicates (tree)
   (let ((seen NIL))
     (labels ((rec (l)
        (cond
          ((null l) NIL)
          ((consp (car l)) (cons (rec (car l))
                                 (rec (cdr l))))
          ((member (car l) seen) (rec (cdr l)))
          (T (push (car l) seen)
             (cons (car l) (rec (cdr l)))))))
       (rec tree))))

这会保留seen中已见过的值的列表,如果再次看到,则会删除这些值。递归函数rec将关闭此值,因此,对于seen的每次调用,所有子列表共享一个multi-level-list-remove-duplicates变量。