【问题标题】:a question on common lisp关于普通 lisp 的一个问题
【发布时间】:2010-04-18 11:30:54
【问题描述】:

这里有个小问题我快疯了, 我不断收到错误,我似乎无法弄清楚为什么, 该代码应该更改列表的范围, 因此,如果我们给它一个包含值 (1 2 3 4) 的列表,并且我们想要将范围从 11 更改为 14,那么结果将是 (11 12 13 14) 问题是最后一个名为scale-list 的函数会返回一个错误:

调试器进入--Lisp 错误: (wrong-type-argument number-or-marker-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)

【问题讨论】:

  • 你的编辑和这个问题有什么关系?
  • 也许他认为编辑是个口齿不清的人!
  • 没有人...但是因为我真的不知道...我想也许编辑器本身就支持一种模式...反正我只是参与了 common lisp 来帮助一个朋友完成他的任务而且我觉得从第 0 天起我就不必了解该语言的所有知识......所以放轻松

标签: common-lisp scaling slime aquamacs


【解决方案1】:

最大值和最小值的定义需要改进。 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。

【讨论】:

  • 这个答案就像梦想成真......非常感谢,我只想提一下,我的一个朋友检查了我在 LispWorks 上的功能并且他们工作,但他们不会在我的电脑上工作在 Aquamacs 上...这听起来对我来说真的很奇怪但无论如何你的实现要好得多,并且可以在两者上运行,非常感谢!
  • @rabidmachine9 : Aquamacs 是你的编辑器,但你用的是什么 Lisp?
  • Slime 只是一种 lisp 交互模式——你使用的是 sbcl 还是 Common Lisp 的其他一些实现?
  • 其实不是...我安装了aquamacs,然后是slime,但仅此而已...还有其他需要吗?
  • @rabidmachine9 :我们在询问您驾驶的是什么车,而您告诉我们您正在使用方向盘。 SLIME 是开发环境,它有两部分:一部分与 Emacs 挂钩,另一部分在一些 Common Lisp 中运行。 SLIME 控制 Common Lisp 实现和 Emacs 之间的通信。那么,您在 SLIME 中使用了哪个 Common Lisp 实现?
【解决方案2】:

我重新发布代码是因为出了点问题...

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

【讨论】:

    【解决方案3】:

    您的实际堆栈跟踪类似于:

    -(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,这会打乱减法。

    【讨论】:

    • 谢谢......如果我给出正确的参数来询问它可以返回的一个值,这个函数最多可以返回一个值......当第二个值被尝试时,问题似乎出现了与第一个缺点...但是是的...这个错误似乎是关于 n 的,对我来说仍然没有意义
    • 在第二次调用 scale-list 时 n-1 nth 返回 nil。我想这只是超出范围 - 通过调试器运行程序添加一些打印语句来监视您的值应该可以帮助您指出问题的确切原因。
    猜你喜欢
    • 1970-01-01
    • 2011-01-15
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 2011-11-18
    相关资源
    最近更新 更多