我在使用 Common Lisp 时遇到了一些麻烦。我想做一个代码来查找列表的值超过或低于两个限制的次数。我想对列表进行扫描并评估当前值是否超过或低于限制。输出应是包含两个值的列表,列表中的值超过上限和低于下限的次数。我尝试使用以下代码:
(defun find-inlist
(y)
(setq upper 0)
(setq lower 0)
(loop for element in y (if (< element 32)(+ lower 1)
(if (> elemen 212)(+ 1 upper))))
(list upper lower))
我使用了以下测试用例,但收到了一条我不明白的错误消息。
find-inlist '(18 75 31 180 270 52 10 215)
Error: LOOP keyword expected in (... (IF (< ELEMENT 32) (+ LOWER 1) (IF (> ELEMEN 212) (+ 1 UPPER)))).
代码上的一些注释。
(defun find-inlist (y)
;; upper and lower are not declared, if the Lisp environment is nice, at
;; best you are modifying global variables, which is not a good idea in
;; general. You can introduce new variables with (let ((upper 0) (lower 0))
;; ...) instead. Since you are using LOOP below, you can also start your
;; LOOP using: LOOP WITH UPPER = 0 AND LOWER = 0, which declares local
;; variables too.
(setq upper 0)
(setq lower 0)
;;
(loop
for element in y
;; (if ...) is an expression, what should be done of the value being
;; computed. Unless you instruct the LOOP macro to do something with it,
;; the value will be discarded. Here you have a syntax error because LOOP
;; expects a keyword, like DO, or COLLECT, etc.
(if (< element 32)
;; (+ x y) computes "x + y", but does not update neither x nor y.
;; Maybe you wanted to assign the computed value to lower?
;;
;; (setf lower (+ lower 1))
;;
;; If so, there is a shorthand notation, which is (incf lower)
;;
(+ lower 1)
;; Same here
(if (> elemen 212)
(+ 1 upper)
)))
;; If you use WITH in the LOOP declaration, then UPPER and LOWER won't be
;; visible here, but you can use FINALLY (RETURN (LIST ...)) in the LOOP.
(list upper lower))