服务器下面的代码,用于显示列表中的整数。
(defun isNum (N)
(and (<= N 9) (>= N 0)))
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
(((and (<= N 9) (>= N 0))) item)(incf count))
(setq(0 + count))))))
运行命令时出现错误A' is not of the expected type
REAL'
(count-numbers'(3 4 5 6 a 7 b))
答案 0 :(得分:6)
我很惊讶它完全运行,因为你的cond
构造不正确,你在代码的不必要的副作用生成位中切换到中缀符号,并且你在{中使用未绑定的变量{1}}。假设,如果它确实运行,那么这个错误听起来是正确的。您正在对参数进行数值比较(以及非数字输入上的错误)。
今天我已经有了我的代码审查帽,所以让我们更深入地了解一下。
Lisp(它实际上无关紧要,这适用于CL,Scheme和所有的mongrels)使用count-numbers
,而不是lower-case-snake-case-with-dashes
用于变量和函数名称。
lowerCamelCase
Common Lisp约定是使用(defun is-num (n)
(and (<= n 9) (>= n 0)))
或p
结束谓词,而不是以-p
开头。 Scheme具有(IMO更好)约定结束谓词is-
而不是
?
(defun num-p (n)
(and (<= n 9) (>= n 0)))
不是你如何调用函数。你实际上需要使用它的名字,而不仅仅是试图调用它的身体。如果您尝试运行此代码,则会出现许多错误之一。
((and (<= N 9) (>= N 0)))
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
((num-p item) item)(incf count))
(setq(0 + count))))))
已经存在,并对其输入进行类型检查,而不是尝试进行数值比较。您可能应该使用它。
numberp
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
((numberp item) item)(incf count))
(setq(0 + count))))))
可能不会按照((numberp item) item) (incf count))
条款执行您认为的操作。它实际上被视为两个单独的条款;一个检查cond
是否为item
,如果是,则返回number
。第二个尝试检查变量incf
并返回count
,如果它的计算结果为t
(它不会,也不会)。您似乎想要的是在列表中找到一个数字时递增计数器count
,这意味着您应该将incf
子句放入item
。
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond ((null list) nil)
((numberp item)
(incf count)
item))
(setq (0 + count)))))
(setq (0 + count))
是错误的
0
和+
作为参数调用函数count
。 / LI>
setq
的第二部分,这意味着您正试图隐含地将上述内容设置为NIL
。此时,我们终于有一段代码可以评估并正常运行(并且它不会引发您在上面提到的错误)。
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond ((null list) nil)
((numberp item)
(incf count)
item))
count)))
dolist
是一个迭代构造,它为给定列表中的每个元素执行某些操作。这意味着您实际上不需要使用cond
手动测试列表终止。此外,由于dolist
未收集结果,因此没有理由将item
返回给它。您还会不必要地隐藏您在count
中声明的本地let
。
(defun count-numbers (list)
(let ((count 0))
(dolist (item list)
(when (numberp item) (incf count)))
count))
像往常一样,您可以通过更简单的loop
来完成所有这些操作。
(defun count-numbers (list)
(loop for item in list
when (numberp item) sum 1))
使计数器隐含,并使您无需手动返回。实际上,除非这是一个编写自己的迭代函数的练习,否则Common Lisp有一个内置的count-if
,它需要predicate sequence [some other options]
并返回count
中sequence
个项目匹配predicate
。如果您想特别命名count-numbers
,出于风格原因,您可以
(defun count-numbers (list) (count-if #'numberp list))
并完成它。
总之,好好尝试,但请在reading up家庭language上尝试for realzies,然后再提出问题。
答案 1 :(得分:0)
另一种方法是:
(reduce
#'(lambda (a b)
(if (numberp b) (1+ a) a))
'(3 4 5 6 a 7 b) :initial-value 0) ; 5
即。以每次迭代给出的方式处理序列,前一次迭代的结果+序列的下一个成员。从零开始并在每次序列中的元素为数字时递增结果。
修改强>
对不起,我还没有看到Inaimathi提到count-if
。那可能会更好。