如何在LISP中将列表转换为集合?

Joe*_*low 0 lisp list common-lisp set

我一直在尝试将线性列表转换为集合,但无济于事。每次运行此命令时,都会出现一些奇怪的编译错误,例如“格式错误的lambda”,它指出了我使用append的方式。这是我的代码:

(defun mem(e l)
  (cond
      ((null l) nil)
      ((equal e (car l)) t)
      ((listp (car l)) (mem e (car l)))
      (t(mem e (cdr l)))
  )
)

(defun st(l k)
  (cond
      ((null l) nil)
      (( mem '(car l) 'k) (st (cdr l) k))
      ((listp (car l)) (st (car l) k))
      ( t (st (cdr l) (append((car l) k)) ))
      (t(mem e (cdr l)))
  )
)
Run Code Online (Sandbox Code Playgroud)

编辑:坦率地说,我只想从列表中删除重复项

Jos*_*lor 5

首选标准库函数

编辑:坦率地说,我只想从列表中删除重复项

Common Lisp具有删除重复功能。该文档包含示例:

例子:

(remove-duplicates "aBcDAbCd" :test #'char-equal :from-end t) =>  "aBcD"
(remove-duplicates '(a b c b d d e)) =>  (A C B D E)
(remove-duplicates '(a b c b d d e) :from-end t) =>  (A B C D E)
(remove-duplicates '((foo #\a) (bar #\%) (baz #\A))
    :test #'char-equal :key #'cadr) =>  ((BAR #\%) (BAZ #\A))
(remove-duplicates '((foo #\a) (bar #\%) (baz #\A)) 
    :test #'char-equal :key #'cadr :from-end t) =>  ((FOO #\a) (BAR #\%))
Run Code Online (Sandbox Code Playgroud)

您是否也在尝试整理清单?

从您的mem代码中,您可以在其中执行以下操作:

  ((listp (car l)) (mem e (car l)))
Run Code Online (Sandbox Code Playgroud)

看起来您希望成员函数也递归到子列表中。即使使用集合,这也有点可疑,因为集合传统上可以包含其他集合。例如,{{3},{4},5}是包含5,集合{3}和集合{4}的集合。这是一样的集合{3,4,5}。您的st函数也似乎正在尝试递归到列表中,这似乎也希望使列表变平。再次,这有点可疑,但是如果您想这样做,那么通过“展平,然后删除重复项”的过程,转换为集合将更加容易:

(defun flatten (list)
  "Returns a fresh list containing the leaf elements of LIST."
  (if (listp list)
      (mapcan 'flatten list)
      (list list)))

;; CL-USER> (flatten '(1 2 (3 4) 5 ((6))))
;; (1 2 3 4 5 6)

(defun to-set (list)
  "Returns a set based on the elements of LIST.  The result
is a flat list containing the leaf elements of LIST, but
with any duplicate elements removed."
  (delete-duplicates (flatten list)))

;; CL-USER> (to-set '(1 3 (3 4) ((4) 5)))
;; (1 3 4 5)
Run Code Online (Sandbox Code Playgroud)

笔记

我收到一些奇怪的编译错误,例如“格式错误的lambda”,它指出了我使用append的方式。

是的,您正在尝试调用append(append((car l)k))。实际上,添加不是问题。请记住,Lisp中函数调用的语法是(function arguments ...)。这意味着您已经:

(append      ((car l) k))
 <function>  <argument1>
Run Code Online (Sandbox Code Playgroud)

但是您的arguments1也是一个函数调用:

((car l)     k          )
 <function>  <argument1>
Run Code Online (Sandbox Code Playgroud)

在Common Lisp中,不能将(car l)用作函数。一个函数可能出现的唯一东西是符号(例如carappend)或lambda表达式(例如(lambda(x)(+ x 1)))。

您想改为呼叫(添加(car l)k)