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的出现次数仍然高于该列表中至少一个元素的出现

这将按升序返回已排序的事件列表。但重复次数最少的元素(与列表的其余部分一致)不应返回。除非所有元素重复相同的次数,否则只有在这种情况下,才会返回所有元素

比如说,

  • (出现次数’(1 2 3))=>(1 2 3),#注意每个元素重复相同的次数

  • (出现次数’(1 1 3))=>(1)#因为列表中1的出现频率高于任何其他元素

  • 3(出现次数’(123466))=>(6)

  • (出现次数’(1130))=>(1,3)#自(12)、(32)及(01)起 因为元素1和3的出现次数仍然高于该列表中至少一个元素的出现次数
  • 注意:现在这个函数返回一个排序列表,但是错误地返回最大值(occ的数量)加上元素,这些元素的出现次数至少不大于列表中的一个其他元素。 前任。
    (出现次数’(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)))