Common Lisp - return 一个元素在列表中出现 n 次的函数

Common Lisp - Function which return an element appears n times in a list

我正在尝试编写一个函数,其中 return 一个元素在列表中出现 n 次。

例如,对于像这样的列表:(setq lst '(a b b b c)),函数 returns :

count-list (lst 3) --> b

但是当有两个(或更多)元素同时出现在 n 中时,函数只 returns 第一个元素:

count-list (lst 1) --> a

而不是

count-list (lst 1) --> a b

函数如下:

(defun count-list (lst nb)
    (loop for x in lst do
        (if (eq (count x lst) nb)
            (return x)
            )
        )
    )

我错过了什么?

我从来没有用过 LISP。我假设你的问题是你的函数 returns 在第一场比赛中。要么在你的函数中创建一个数组来存储所有出现 n 次的元素,然后 return 到该数组,或者,例如,在 Python 中我会使用 print(x) 所以函数不会 return 在第一场比赛中,就像你的情况一样。

return 告诉计数列表函数一旦找到命中就立即退出,因此它不会寻找与计数匹配的其他元素。 一种可能的解决方案是:

(defun count-list (lst n) 
  (remove-duplicates 
    (mapcan #'(lambda (x) 
                (when (eql (count x lst) n) 
                  (list x) )) 
         lst )))

然而,这是非常低效的,因为对于每个项目,列表必须遍历两次,一次用于函数本身,一次用于计数,因此这将花费与列表长度的平方成正比的时间。
一种更有效的方法是累积值(例如,在关联列表中)并在末尾 select 那些与输入计数匹配的项目。

  (defun count-list (lst n)
    (let* (count-list pair)
      (dolist (x lst)
        (if (setq pair (assoc x count-list))
          (incf (cdr pair))
          (push (cons x 1) count-list) ))
      (mapcan #'(lambda (pair) 
                  (when (eql n (cdr pair))
                     (list (car pair)) )) 
              count-list )))