如何在Lisp Works中对包含数字和字母的列表求和
我试图定义一个以列表为参数的求和函数。问题是我的列表不仅可以包含数字,还可以包含字母。所以我的问题是,我如何避免这些信件,并继续验证列表的其余部分 例:(和)(a 2 4 b d))=6 我只有一个“堆栈溢出”错误如何在Lisp Works中对包含数字和字母的列表求和,lisp,common-lisp,clisp,Lisp,Common Lisp,Clisp,我试图定义一个以列表为参数的求和函数。问题是我的列表不仅可以包含数字,还可以包含字母。所以我的问题是,我如何避免这些信件,并继续验证列表的其余部分 例:(和)(a 2 4 b d))=6 我只有一个“堆栈溢出”错误 提前感谢。这不是最有效的方法,但请将函数remove if(或delete if)与numberp一起检查。您的代码尝试应用递归方法。在这里,它的格式正确,名称较长: (defun sum (list) (if (numberp (car list)) (sum (
提前感谢。这不是最有效的方法,但请将函数remove if(或delete if)与numberp一起检查。您的代码尝试应用递归方法。在这里,它的格式正确,名称较长:
(defun sum (list)
(if (numberp (car list))
(sum (cdr list))
(+ (car list) (sum (cdr list)))))
由于列表为空时未提供基本大小写,因此出现堆栈溢出。
如果将一个NIL列表传递到函数中,会发生什么
(汽车列表)
返回NIL,它不是一个数字(car list)
添加到递归调用中,以使用同样为零的(cdr list)
求和etypecase
,因为它提供了一种防御性的编码方法,可以尽早拒绝错误,并且非常便于阅读:
(defun foo (list)
(etypecase list
(null <base-case>)
(cons <general-case>)))
这可能是对学生的期望。更好的方法是使用endp
而不是null
,因为前者检查参数是否有效地是一个列表
在你的问题中:
- 基本情况显然返回0
- 一般情况下,用递归获得的
之和计算cdr
(如果不是数字,则为零)之和car
(loop for e in list when (numberp e) sum e)
如果您对高阶函数感兴趣,以下操作也可以,但会分配一个中间列表(这是否可接受取决于列表的预期大小):
你好,谢谢你的解释!我尝试了“cond”方法,但仍然出现错误。我的函数是
(defun sum(liste)(cond((null liste)nil)((numberp(car liste))(+(car liste)(sum(cdr liste))))((sum(cdr liste))))
错误消息是“In+of(2 nil)参数应为NUMBER类型”。对于(sum'(2)),空列表的和应为零。在这里,您尝试向nil添加一个未定义的数字。嗨,leo,最后我使用了remove if,它工作得很好!谢谢你们
(defun foo (list)
(if (null list)
<base-case>
<general-case>))
(loop for e in list when (numberp e) sum e)
(reduce #'+ (remove-if-not #'numberp list))