Lisp函数的另一种细化

Lisp函数的另一种细化,lisp,common-lisp,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

我已经完成了格雷厄姆的练习第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”的(length vec)默认值,但end的默认值变为nil。
我们有明确的指示,“长度”最多只能调用一次。

你能给我一些提示吗?谢谢。

我不知道您正在使用的一些lisp功能,但在我看来,您的老师是不正确的

如果函数采用start和end,则长度既不需要也不正确。长度可以为0,但重要的是start是否 在我看来,
length
end
的默认值,您只测试
end
,根本不测试
length
。。。他的抱怨似乎已经得到了解决


也就是说,该代码中还有其他一些问题值得抱怨。例如,如果使用
end
<
start
调用max-min,会发生什么情况?在我看来,您将通过递增start进行递归,直到向量用完,然后您将得到某种异常。

您的lambda列表正常。问题在于基本情况:
(zerop end)
应该进行修改,以便在像
(minmax myvec:start 5:end 3)
那样调用时也能得到合理的结果

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

   (multiple-value-bind (x y) (max-min vec :start (1+ start) :end end)
   (let* ((maxx x) (minn y))
     ;; ...
如果希望将递归调用的结果命名为
maxx
minn
,为什么不直接这样命名呢

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

顺便说一下,您可以调用它们
max
min
(变量和函数有单独的名称空间),或者
max of rest
min of rest
(更具描述性)。

您是否尝试过使用start=5和end=2调用函数?为什么使用LET*?为了什么?是的,我有。我想那会管用的。(>=开始-结束)会发生什么?哦,这真是个好主意,雷纳。我只是遵循讲师给我们的递归格式,对于递归,使用let初始化局部变量。现在我开始意识到,我已经在x和y中有了它们,真的没有必要让它们变成两个额外的maxx和minn!谢谢你,艾迪安,你帮了我大忙。我也很难理解他,真的不知道他真正的意思。事实上,如果一个练习被这位老师标记为“几乎完成”,那就意味着只需要做一个很小的改变。所以我现在正在研究这一部分。顺便问一下,你的意思是“结束”的默认值是向量的长度吗?谢谢。是的,对不起,说错了。但我不能肯定,我从未使用过&关键参数。不过,在我看来,这绝对是个样子。