2009-07-11 5 views
2

aufaddieren Ich habe einen Eingang, der diese Form ist:Wie die Elemente für eine Struktur in Scheme/Lisp

(((lady-in-water . 1.25) 
    (snake . 1.75) 
    (run . 2.25) 
    (just-my-luck . 1.5)) 
((lady-in-water . 0.8235294117647058) 
    (snake . 0.5882352941176471) 
    (just-my-luck . 0.8235294117647058)) 
((lady-in-water . 0.8888888888888888) 
    (snake . 1.5555555555555554) 
    (just-my-luck . 1.3333333333333333))) 

(Kontext: das Wort bezeichnet einen Film und die Zahl bezeichnet die gewichtete Bewertung vorgelegt von der Benutzer)

ich brauche die ganze Menge hinzuzufügen und eine Liste zurück, die

((lady-in-water 2.5) 
(snake 2.5) 
(run 2.25) 
(just-myluck 2.6)) 

etwa wie folgt aussieht Wie kann ich die Liste und alle Mengen durchqueren? Ich bin wirklich ratlos. Bitte hilf mir.

Danke.

+0

Ich liebe Lisp. Es macht mich immer glücklich, Lisp Fragen hier zu sehen. –

Antwort

1

Um den falschen Eindruck zu vermeiden, dass CL in irgendeiner Weise überlegen ist, hier ist eine PLT-Schema-Lösung mit dem Hash-Ta Annäherung. Ich habe eine sort der Ergebnisse für zusätzlichen Kredit hinzugefügt.

(define (data->movies data) 
    (define t (make-hasheq)) 
    (for* ([x (in-list data)] [x (in-list x)]) 
    (hash-set! t (car x) (+ (cdr x) (hash-ref t (car x) 0)))) 
    (sort (hash-map t cons) > #:key cdr)) 
+0

Wie immer Eli, das ist genial. Jeder verneigt sich vor deinem neuen Meister. – unj2

1

Sie müssen das Problem in zwei Teile brechen: Erstens, verwandeln die Liste in etwa wie folgt:

'(((lady-in-water . 1.25) (lady-in-water . 0.82) (lady-in-water . 0.88)) 
    ((snake . 1.75) ...) 
    ...) 

Ich werde tun, dass die Verwendung von transpose:

(define (transpose ls) 
    (if (null? (car ls)) 
     '() 
     (cons (map car ls) (transpose (map cdr ls))))) 

Dann ist es leicht zu die transponierte Filmliste auf eine einzelne Liste von Paaren reduzieren:

(define (sum-movie movie) 
    (cons (caar movie) (apply + (map cdr movie)))) 
(define (sum-movies movies) 
    (map sum-movie (transpose movies))) 

Beachten Sie, dass transpose ist unsicher: Es wird abstürzen, wenn Sie einen Film in einer Unterliste verpassen. Auch bei der Verwendung von transpose wird davon ausgegangen, dass Filme jedes Mal in der gleichen Reihenfolge kommen.

+0

das ist interessant, aber wie du sagtest sehr riskant. aber eine nette nathan, danke. – unj2

1

In Common Lisp:

(defun marginalize (data) 
    (let ((table (make-hash-table))) 
    (loop for row in data do 
     (loop for (k . v) in row do 
     (incf (gethash k table 0.0) v))) 
    (loop for k being the hash-key of table using (hash-value v) 
      collect (cons k v)))) 
2

Mein Ansatz ist ähnlich der oben Huaiyuan, aber ich ziehe Dolist Schleife mit:

(defun parse-ratings (all-ratings) 
    (let ((hash (make-hash-table))) 
    (dolist (rating-list all-ratings) 
     (dolist (rating rating-list) 
     (incf (gethash (car rating) hash 0) 
       (cdr rating)))) 
    (maphash (lambda (key value) 
       (format t "total for ~a: ~a~%" key value)) 
      hash))) 

, die in der folgenden Ausgabe führt:

CL-USER> (parse-ratings '(((lady-in-water . 1.25) (snake . 1.75) 
          (run . 2.25) (just-my-luck . 1.5)) 
         ((lady-in-water . 0.8235294117647058) 
          (snake . 0.5882352941176471) 
          (just-my-luck . 0.8235294117647058)) 
         ((lady-in-water . 0.8888888888888888) 
          (snake . 1.5555555555555554) 
          (just-my-luck . 1.3333333333333333)))) 
total for LADY-IN-WATER: 2.9624183 
total for SNAKE: 3.893791 
total for RUN: 2.25 
total for JUST-MY-LUCK: 3.6568627 
NIL 
CL-USER>