2011-09-22 14 views
5

は今、私はそれをソートする前に、リストに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個の要素を取り出すためのより良い方法は何ですか?

+1

あなたの質問がありますか?タイトルのものか内容のものか? –

+0

タイトルとコメントのどちらかに答えるだけで建設的なのでしょうか? – Paralife

答えて

10

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コミュニティで広く使用されています。

第2の関数は、各ペアのCDRをキーとして使用して、最初の関数によって返されたalistをソートすることによって返されたリストから最初のN個のアイテムを取得するためにSUBSEQを使用します。変更:キーを# 'に変更するとハッシュキーでソートされ、#'>を# 'に変更すると、ソート順が逆転します。

2

ハッシュテーブルは、本質的に順序付けられていません。ソートしたい場合は、その内容を使って順序付けられたデータ構造を初期化する必要があります。

シーケンスの最初のN要素をフェッチする場合は、常にSUBSEQがあります。

関連する問題