1

ここで小さな問題に夢中になっています。エラーが発生し続け、理由がわからないようです。コードはリストの範囲を変更することになっているので、値(1 2 3 4)を含むリストを指定して、 11から14の範囲を変更すると(11 12 13 14) 、問題は、最後に呼び出された関数scale-listが次のようなエラーを返すことです。

デバッガーが入力されました--Lispエラー:(間違ったタイプの引数番号またはマーカー-pnil)

誰かがなぜ手がかりを持っていますか?よろしくお願いします。

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

3 に答える 3

4

最大値と最小値の定義を改善する必要があります。SORT は破壊的です。'(1 2 3 4) のようなリテラル定数を使用して SORT を呼び出すことも間違っています。繰り返しになりますが、SORT は破壊的です。

より良い定義:

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

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

範囲のより効率的な定義:

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

SCALE-LIST と SCALE-VALUE も Lisp 風ではありません。再帰関数でこのように NTH を呼び出すと、何か問題があります。インデックスではなく、リストを再帰する必要があります。SCALE-VALUE は、呼び出しごとに RANGE と MINIMUM を呼び出します。なんで?

このバリアントを確認してください:

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

さらに改善できることは何ですか?たとえば、再帰を取り除き、MAPCAR に置き換えます。

于 2010-04-18T16:11:33.910 に答える
0

何か問題が発生したため、コードを再投稿します...

;;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)
于 2010-04-18T11:37:12.270 に答える
0

実際のスタックトレースは次のようなものです。

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

間違ったn番目の要素を判別すると、nilが返され、減算が台無しになります。

于 2010-04-18T11:43:25.837 に答える