Frage

Ich bin immer verrückt mit einem kleinen Problem hier, Ich halte einen Fehler bekommen, und ich kann nicht scheinen, um herauszufinden, warum, der Code soll die Reichweite einer Liste ändern, so, wenn wir sie geben eine Liste mit Werten (1 2 3 4) und wir wollen den Bereich, in 11 bis vierzehn um das Ergebnis ändern (11 12 13 14) wäre das Problem ist, dass die letzte Funktion aufgerufen scale-list wird einen Fehler zurückgeben sagen:

  

Debugger eingegeben - Lisp-Fehler: (falsches-Typ-Argument Nummer-oder-Marker-p null)

jemand hat eine Ahnung, warum? Ich benutze Aquamacs als Redakteur Vielen Dank im Voraus

;;finds minimum in a list
(defun minimum (list)
  (car (sort list #'<)))

;;finds maximum in a list
(defun maximum (list)
  (car (sort list #'>)))

;;calculates the range of a list
(defun range (list)
  (- (maximum list) (minimum list)))

;;scales one value to another range
(defun scale-value (list low high n)
   (+ (/ (* (- (nth (- n 1) list)
               (minimum list))
            (- high low))
         (range list))
      low))


;;is supposed to scale the whole list to another range
(defun scale-list (list low high n)
  (unless (= n 0)
   (cons (scale-value list low high n)
         (scale-list list low high (- n 1)))))

(scale-list '(1 2 3 4) 21 24 4)
War es hilfreich?

Lösung

Die Definitionen von Maximal- und Minimal müssen verbessert werden. SORT ist zerstörerisch. Es ist auch falsch wie ‚SORT mit einer Literalkonstante zu nennen (1 2 3 4) -. Wieder, SORT destruktiv

Bessere Definitionen:

(defun minimum (list)
  (reduce #'min list))

(defun maximum (list)
  (reduce #'max list))

Eine effizientere Definition des Bereichs:

(defun range (list)
  (loop for e in list
        maximize e into max
        minimize e into min
        finally (return (- max min))))

SCALE-LIST und SCALE-VALUE ist auch nicht Lisp-like. Wenn Sie NTH wie dies in einer rekursiven Funktion aufrufen, dann ist etwas falsch. Sie sollten die Liste, nicht der Index Rekursion über. SCALE-VALUE ruft Bereich und eine minimale für jeden Anruf. Warum?

Sehen Sie sich diese Variante:

;;scales one value to another range
(defun scale-value (item low high min range)
   (+ (/ (* (- item min)
            (- high low))
         range)
      low))

;;is supposed to scale the whole list to another range
(defun scale-list (list low high)
  (let ((min (minimum list))
        (range (range list)))
    (labels ((scale-list-aux (list)
               (when list
                 (cons (scale-value (first list) low high min range)
                       (scale-list-aux (rest list))))))
      (scale-list-aux list))))

(scale-list '(1 2 3 4) 21 24)

Was kann man mehr verbessern? Zum Beispiel würde ich loswerden der Rekursion erhalten und ersetzen sie durch mapcar.

Andere Tipps

ich erneut nach dem Code, weil etwas schief gelaufen ist ...

;;finds minimum in a list
(defun minimum(list)
  (car  (sort list #'<)))
;;finds maximum in a list
(defun maximum(list)
  (car (sort list #'>)))
;;calculates the range of a list
(defun range(list)
  (- (maximum list) (minimum list)))

;;scales one value to another range
(defun scale-value(list low high n)
     (+ (/ (* (- (nth (- n 1) list) (minimum list)) (- high low)) (range list)) low))


;;is supposed to scale the whole list to another range
(defun scale-list(list low high n)
  (unless (= n 0)
   (cons (scale-value list low high n) (scale-list list low high (- n 1)))))

(scale-list '(1 2 3 4) 21 24 4)

Ihre tatsächliche Stack-Trace ist so etwas wie:

-(nil 0.1)
  (* (- (nth ... list) (minimum list)) (- high low))
  (/ (* (- ... ...) (- high low)) (range list))
  (+ (/ (* ... ...) (range list)) low)
  scale-value((0.1) 20 30 3)

Ich denke, man ein falsches n-te Element bestimmen und diese gibt nil zurück, die verunstaltet die Subtraktion.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top