现在我必须在将hastable复制到列表之前将其复制到列表中:
(defun good-red ()
(let ((tab (make-hash-table)) (res '()))
(dotimes (i 33) (setf (gethash (+ i 1) tab) 0))
(with-open-file (stream "test.txt")
(loop for line = (read-line stream nil)
until (null line)
do
(setq nums (butlast (str2lst (substring line 6))))
(dolist (n nums) (incf (gethash n tab)))
))
**(maphash #'(lambda (k v) (push (cons k v) res)) tab)**
(setq sort-res (sort res #'< :key #'cdr))
(reverse (nthcdr (- 33 18) (mapcar #'car sort-res))) ))
BTW,获取列表的前N个元素的更好方法是什么?
答案 0 :(得分:12)
Vatine的回答在技术上是正确的,但对于某人提出这个问题的直接问题可能并不是非常有用。使用哈希表来保存计数器集合,然后按分数选择前N项的常见情况可以这样做:
;; convert the hash table into an association list
(defun hash-table-alist (table)
"Returns an association list containing the keys and values of hash table TABLE."
(let ((alist nil))
(maphash (lambda (k v)
(push (cons k v) alist))
table)
alist))
(defun hash-table-top-n-values (table n)
"Returns the top N entries from hash table TABLE. Values are expected to be numeric."
(subseq (sort (hash-table-alist table) #'> :key #'cdr) 0 n))
第一个函数将哈希表的内容作为列表中的一系列 cons 'd对返回,称为关联列表(键/值对的典型列表表示)。大多数Lisp爱好者已经掌握了这个功能的变体,因为它是如此常见的操作。此版本来自Alexandria库,该库在CL社区中使用得非常广泛。
第二个函数使用SUBSEQ从第一个函数返回的alist中排序返回的列表中的前N个项目,使用每对的CDR作为键。更改:#'车钥匙将按哈希键排序,更改#'&gt;到#'&lt;会颠倒排序顺序。
答案 1 :(得分:3)
哈希表本质上是无序的。如果要对其进行排序,则需要使用内容初始化某种有序数据结构。
如果你想获取一个序列的前N个元素,总会有SUBSEQ。