【问题标题】:What's the best way to sort a hashtable by value?按值对哈希表进行排序的最佳方法是什么?
【发布时间】:2011-11-22 10:25:03
【问题描述】:

现在我必须在排序之前将 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))) ))

顺便说一句,获取列表的前 N ​​个元素的更好方法是什么?

【问题讨论】:

  • 你有什么问题?是标题中的那个,还是内容中的那个?
  • 只回答标题中的那个和/或 cmets 中的那个不是更有建设性吗?

标签: lisp clisp


【解决方案1】:

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 对返回,该列表称为关联列表(键/值对的典型列表表示)。大多数 Lisp 爱好者手头已经有了这个功能的变体,因为它是一种非常常见的操作。此版本来自Alexandria 库,在 CL 社区中应用非常广泛。

第二个函数使用 SUBSEQ 从返回的列表中获取前 N 个项目,该列表通过使用每对的 CDR 作为键对第一个函数返回的 alist 进行排序来获取。将 :key 更改为 #'car 将按哈希键排序,将 #'> 更改为 #'

【讨论】:

    【解决方案2】:

    哈希表本质上是无序的。如果要对其进行排序,则需要使用内容初始化某种有序的数据结构。

    如果你想获取一个序列的前 N ​​个元素,总有 SUBSEQ。

    【讨论】:

      猜你喜欢
      • 2015-09-16
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-27
      • 2010-12-16
      相关资源
      最近更新 更多