Lisp 查找列表中出现次数最多的元素,并返回以出现次数最多的元素开头的列表
这将按升序返回已排序的事件列表。但重复次数最少的元素(与列表的其余部分一致)不应返回。除非所有元素重复相同的次数,否则只有在这种情况下,才会返回所有元素 比如说,Lisp 查找列表中出现次数最多的元素,并返回以出现次数最多的元素开头的列表,lisp,common-lisp,Lisp,Common Lisp,这将按升序返回已排序的事件列表。但重复次数最少的元素(与列表的其余部分一致)不应返回。除非所有元素重复相同的次数,否则只有在这种情况下,才会返回所有元素 比如说, (出现次数’(1 2 3))=>(1 2 3),#注意每个元素重复相同的次数 (出现次数’(1 1 3))=>(1)#因为列表中1的出现频率高于任何其他元素 3(出现次数’(123466))=>(6) (出现次数’(1130))=>(1,3)#自(12)、(32)及(01)起 因为元素1和3的出现次数仍然高于该列表中至少一个元素的出现
(出现次数’(7 7 1 2 3))返回(7 1 2 3),但应仅返回7。如果您能帮助修复此函数以返回预期结果,我将不胜感激。使用初始方法的解决方案如下:
(defun occurrences (l)
(let (
(result (mapcar #'(lambda (elt) (cons elt (count elt l)) )
(remove-duplicates l) ) )
(result2 nil)
(result3 nil)
(result4 nil)
)
(progn
(sort result #'> :key #'cdr)
(loop for x in result
do (and(push (car x) result2)(push (cdr x) result3))
)
)))
但是,该解决方案效率不高,因为它的成本为O(n2)(在初始阶段,将列表中的每个元素与所有其他元素进行比较以计算其频率)
编辑
例如,可以通过使用哈希表获得更有效的解决方案(在@uselpa的评论中建议进行改进):
您可以使用
(let((max count(l中elt的循环最大化)(incf(gethash elt table 0)))保存一个过程。
@uselpa,这是一个非常优雅的过程,谢谢!我已经更新了答案。
(defun max-occurrences(l)
(let* ((occurrences (remove-duplicates
(mapcar #'(lambda (elt) (cons elt (count elt l))) l)
:test 'equal))
(max-occurrence (reduce #'max occurrences :initial-value 0 :key #'cdr)))
(mapcar #'car (remove-if-not (lambda(x) (= x max-occurrence)) occurrences :key #'cdr))))
(defun max-occurrences(l)
(let* ((table (make-hash-table))
(max-count (loop for elt in l maximize (incf (gethash elt table 0)))))
(loop for elt being the hash-key of table using (hash-value count)
when (= count max-count) collect elt)))