2011-09-22 15 views
5

ahora tengo que copiar el hastable a una lista antes de la clasificación que:¿Cuál es la mejor forma de ordenar una tabla hash por valor?

(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))))) 

Por cierto, ¿cuál es la mejor manera de obtener los primeros N elementos de una lista?

+1

¿Cuál es tu pregunta? ¿La del título o la del contenido? –

+0

¿No sería más constructivo simplemente responder a la del título y/o la de los comentarios? – Paralife

Respuesta

10

La respuesta de Vatine es técnicamente correcta, pero probablemente no muy útil para el problema inmediato de alguien que hace esta pregunta. El caso común de usar una tabla hash para mantener una colección de contadores, a continuación, seleccionar los mejores N elementos por puntuación se puede hacer así:

;; 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)) 

La primera función devuelve el contenido de una tabla hash como una serie de cons 'd pares en una lista, que se llama una lista de asociación (la típica representación de lista para pares clave/valor). La mayoría de los entusiastas de Lisp ya tienen una variación de esta función en la mano porque es una operación tan común. Esta versión es de la biblioteca Alexandria, que es muy utilizada en la comunidad de CL.

La segunda función usa SUBSEQ para tomar los primeros N elementos de la lista devuelta ordenando la alista devuelta por la primera función usando el CDR de cada par como la clave. Cambiando: la clave para # 'auto ordenaría por las teclas hash, cambiando #'> a # '< invertiría el orden de clasificación.

2

Una hash-table está inherentemente desordenada. Si lo quiere ordenado, debe inicializar algún tipo de estructura de datos ordenada con los contenidos.

Si quiere buscar los primeros N elementos de una secuencia, siempre hay SUBSEQ.

Cuestiones relacionadas