另一个Lisp函数细化

时间:2009-12-09 22:17:13

标签: lisp common-lisp

我已经完成了格雷厄姆的第5.8章练习,我的代码是:

(defun max-min (vec &key (start 0) (end (length vec)))
  (cond 
    ((eql start (1- end)) (values (elt vec start) (elt vec (1- end))))
    ((zerop end) (values nil nil))
    (t 
       (multiple-value-bind (x y) (max-min vec :start (1+ start) :end end)
       (let* ((maxx x)(minn y))
         (values (max maxx (elt vec start)) (min minn (elt vec start))))))))

您无需担心细节,基本上它只是以“值”形式返回给定矢量的最大值和最小值。
我使用上面的递归来解决问题,但是我的老师用我的批评来标记我的功能“差不多完成了”:

“如果一个函数需要开始和结束,那么长度既不需要也不正确。长度可以是> 0但是它是否开始<结束或者不重要。测试结束全部本身并不相关。”

我现在还不是很清楚,我试图摆脱“end”的(长度vec)默认值,但是end的默认值变为nil。
我们有明确的说法,“长度”最多应调用一次 你能给我一些暗示吗?感谢。

2 个答案:

答案 0 :(得分:4)

你的lambda列表没问题。问题是基本情况:(zerop end)应该被修改,以便在(min-max myvec :start 5 :end 3)调用时也能获得合理的结果。

下一个批评是关于这两行:

   (multiple-value-bind (x y) (max-min vec :start (1+ start) :end end)
   (let* ((maxx x) (minn y))
     ;; ...

如果您希望将递归调用的结果命名为maxxminn,为什么不直接将它们命名为?

   (multiple-value-bind (maxx minn) (max-min vec :start (1+ start) :end end)
     ;; ...

顺便说一句,您可以将它们称为maxmin(变量和函数有单独的命名空间),或max-of-restmin-of-rest(更具描述性) )。

答案 1 :(得分:0)

我不知道您正在使用的某些lisp功能,但它在我看来非常像您的老师不正确。

  

“如果一个函数需要开始和结束,那么长度既不需要也不正确。长度可以是0,但是它是否开始<结束或者不重要。测试结束本身并不重要。”

我认为lengthend的默认值,而您 仅测试end,而不测试length他的抱怨似乎已得到解决。

也就是说,在该代码中还有其他一些要抱怨的事情。例如,如果您使用end<来调用max-min会发生什么? start?它看起来像你会通过递增开始来递减,直到你用完向量,然后你会得到某种异常。