1

我对这里的一个小问题感到疯狂,我不断收到错误,我似乎无法弄清楚为什么,代码应该改变列表的范围,所以如果我们给它一个带有值的列表(1 2 3 4)并且我们想要将范围从 11 更改为 14 结果将是(11 12 13 14) 问题是最后一个调用的函数scale-list将返回一个错误说:

调试器进入--Lisp 错误:(错误类型参数编号-或标记-p nil)

有人知道为什么吗?我使用 aquamacs 作为编辑提前谢谢

;;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 回答