如何在常见的lisp列表中找到最常见的元素?

时间:2016-10-10 23:45:04

标签: lisp common-lisp

假设我们有一个包含这些元素的列表:

(“苹果”“梨”“苹果”“香蕉”“梨”“苹果”)

如何确定这个列表中最常见的元素是“apple”?

1 个答案:

答案 0 :(得分:4)

问题非常广泛,因此下面是一个实用功能,它将元素分组到相同频率的包中。主返回值是哈希表,其中键是正数(出现次数)和值的元素列表。所有这些列表构成elements的分区。 辅助返回值是中频哈希表,它可能对调用者有用。您应该能够找到最常出现的元素。

(defun frequency-bags (elements &key (test #'equal))
  (let ((frequencies (make-hash-table :test test))
        (bags (make-hash-table :test #'eql)))
    (dolist (e elements) (incf (gethash e frequencies 0)))
    (maphash (lambda (k v) (push k (gethash v bags))) frequencies)
    (values bags frequencies)))

参考

make-hash-table gethash maphash dolist values setf push

实施例

(alexandria:hash-table-alist 
 (frequency-bags
  '("apple" "pear" "apple" "banana" "pear" "pear" "apple")))

=> ((1 "banana")
    (3 "pear" "apple"))

(alexandria:hash-table-alist 
 (frequency-bags
  '("apple" "apple" "orange" "peach" "banana" "pear" "pear" "apple")))

=> ((2 "pear")
    (1 "banana" "peach" "orange")
    (3 "apple"))