为什么我的Common Lisp循环只适用于简单的代码?

时间:2011-11-06 13:52:55

标签: loops for-loop lisp common-lisp

我有一些代码:

(defun divisor (x)
  (loop for i from 2 to x do
       (if (= x i) (return x) 
           (if (not (mod x i))
               (return (append i (divisor (/ x i))))))))

应该返回x的素因子列表。但是,代码只返回x。

defun评估没有错误。我试图跟踪defun中的每个函数,并且没有评估过。循环是一个宏,所以我无法追踪它,但如果我清除循环内部并替换为

(format t "~d " i)

它从2到x计数,就像我期望的那样。

我认为我做错了什么,但我无法理解。

3 个答案:

答案 0 :(得分:6)

一个问题是您使用(not (mod x i))来确定mod评估是否为0,这是错误的。

另一个问题是你将原子附加到列表中,我认为它不是你想要做的。

这是一个似乎有效的修订版本:

(defun divisor (x)
  (loop for i from 2 to x do
       (if (= x i) (return (list x))
           (if (= (mod x i) 0)
               (return (append (list i) (divisor (/ x i))))))))

答案 1 :(得分:2)

在你的循环中,我最终到达x。那么你返回x,丢弃你可能从子递归中返回的任何其他返回值。

我认为你已经不正确地将循环与递归相结合。你只需要做其中一个。

答案 2 :(得分:1)

    (defun divisor (x) 
      (loop for i from 2 to x when (eql 0 (mod x i)) collect i))