【问题标题】:lisp iterative function always returns nillisp 迭代函数总是返回 nil
【发布时间】:2012-09-15 21:16:42
【问题描述】:

这个函数应该计算元素“a”出现在列表中的次数,但不起作用:

(defun iter-a_count (lst)
   (let ((count 0))
        (dolist (x lst)
                (if (equal x 'a) 
                    (setf count (+ count 1)))
         count )))

这个函数总是返回 nil。请问我哪里出错了?

【问题讨论】:

    标签: lisp iteration let


    【解决方案1】:

    dolist 宏返回的值是它的第三个“参数”,即

    (dolist (iterator iterable result) forms)
    

    其中iterator 每次迭代都会更新为iterable 的下一个单元格的car,在访问完所有列表单元格后,返回result

    您没有指定结果,结果的默认值为nil。我不确定最后一行中 count 的用途是什么 - 也许您想返回 count - 在这种情况下,请将其放在 lst 之后。

    您还想考虑几件事:

    (setf x (+ x 1))
    

    相当于:

    (setf x (1+ x))
    

    相当于:

    (incf x)
    

    写起来比较惯用

    (when x forms)
    

    而不是

    (if x true-branch)
    

    因为如果您以后想要向 true-branch 添加更多表达式,则必须将它们包装在 progn 中 - 这只会使代码混乱。

    此外,您正在做(或似乎在做)的事情,可以通过使用适当的谓词调用 count-if 来代替。

    (defun count-a (list)
      (count-if #'(lambda (x) (equal x 'a)) list))
    
    (count-a '(a b c d a b a d a c b d e))  ; 4
    

    【讨论】:

    • 非常感谢,我输入了count作为第三个参数,现在函数可以工作了。感谢您提供有关 count-if 的信息。现在我将尝试 count-a 的递归版本。
    【解决方案2】:

    请问我哪里出错了?

    缩进(如,你缩进错误):你写了

    (defun iter-a_count (lst)
      (let ((count 0))
        (dolist (x lst)
          (if (equal x 'a) 
              (setf count (+ count 1)))
          count)))
    

    但我认为你的意思是

    (defun iter-a_count (lst)
      (let ((count 0))
        (dolist (x lst)
          (if (equal x 'a) 
              (setf count (+ count 1))))
        count))
    

    【讨论】:

      猜你喜欢
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      • 2018-02-19
      • 1970-01-01
      • 2017-03-28
      • 2015-03-05
      • 2014-08-25
      • 2016-05-17
      相关资源
      最近更新 更多