Question

je deviens fou avec un petit problème ici, Je continue à obtenir une erreur et je ne peux pas sembler comprendre pourquoi, le code est censé modifier la plage d'une liste, donc si nous lui donnons une liste des valeurs (1 2 3 4) et nous voulons changer la gamme de 11 à quatorze ans le résultat serait (11 12 13 14) le problème est que la dernière fonction appelée scale-list redonnera une erreur en disant:

  

Debugger est entré - erreur Lisp: (mauvais type argument nul numéro ou marqueur-p)

personne

a un indice pourquoi? J'utilise Aquamacs comme éditeur merci à l'avance

;;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)
Était-ce utile?

La solution

Les définitions des besoins maximum et minimum à améliorer. SORT est destructrice. Il est également erroné d'appeler SORT avec une constante littérale comme « (1 2 3 4) -. À nouveau, SORT est destructrice

De meilleures définitions:

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

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

Une définition plus efficace de la gamme:

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

SCALE-LIST et SCALE-valeur sont pas non plus Lisp. Si vous appelez NTH comme ça dans une fonction récursive alors quelque chose ne va pas. Vous devez récursif sur la liste, pas l'index. ÉCHELLE VALEUR appelle RANGE et minimum pour chaque appel. Pourquoi?

Cochez cette 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)

Que pouvez-vous améliorer plus? Par exemple, je supprimerais la récursivité et le remplacer par MAPCAR.

Autres conseils

Je re poster le code parce que quelque chose a mal tourné ...

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

Votre trace de la pile réelle est quelque chose comme:

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

Je suppose que vous déterminez un mauvais élément n-ième et ce rendement nul, ce qui endommagerait la soustraction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top