Common Lisp 上的 If 循环问题

问题描述 投票:0回答:1

我在使用 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)))).

common-lisp
1个回答
0
投票

代码上的一些注释。

(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))
© www.soinside.com 2019 - 2024. All rights reserved.