&引用;堆栈溢出(深)";Lisp中的错误

&引用;堆栈溢出(深)";Lisp中的错误,lisp,common-lisp,Lisp,Common Lisp,我正在尝试创建一个函数prime factors,它返回一个数字的prime factors。为此,我创建了is prime函数和prime factors helper,它将对prime factors进行递归检查 (defun is-prime (n &optional (d (- n 1))) (if (/= n 1) (or (= d 1) (and (/= (rem n d) 0) (is-prime n (- d 1)

我正在尝试创建一个函数
prime factors
,它返回一个数字的prime factors。为此,我创建了
is prime
函数和
prime factors helper
,它将对prime factors进行递归检查

(defun is-prime (n &optional (d (- n 1))) 
  (if (/= n 1) (or (= d 1)
          (and (/= (rem n d) 0)
               (is-prime  n (- d 1)))) ()))

(defun prime-factors-helper (x n)
   (if (is-prime x) (list x) 
        (if (is-prime n) 
            (if (AND (= (mod x n) 0) (< n (/ x 2)))
                (append (list n) (prime-factors-helper (/ x n) (+ 1 n)))
                (prime-factors-helper x (+ 1 n)))       
            (prime-factors-helper x (+ 1 n)))))

(defun prime-factors (x)
    (prime-factors-helper x 2)) 
你能告诉我为什么它会返回这个错误吗?递归调用有什么问题吗

[更新]

我重新定义了
is prime
函数,但显然这不是问题所在

(defun is-prime (x &optional (i 2))
    (if (= x 1) nil
        (if (or (= x 2) (= x 3)) t
            (if (<= i (sqrt x))
                (if (= (mod x i ) 0) nil
                    (is-prime x (+ i 1)))
                t))))



(defun prime-factors-helper (x n)
   (if (is-prime x) 
       (list x) 
       (if (is-prime n) 
            (if (AND (= (mod x n) 0) (<= n (/ x 2)))
                (cons n (prime-factors-helper (/ x n) n))
                (prime-factors-helper x (+ 1 n)))       
            (prime-factors-helper x (+ 1 n)))))
(defun是prime(x&可选(i2))
(如果(=x1)无
(如果(或(=x2)(=x3))t

(如果(关于代码的一些一般性评论:

(defun is-prime (x &optional (i 2))
    (if (= x 1) nil
        (if (or (= x 2) (= x 3)) t
            (if (<= i (sqrt x))
                (if (= (mod x i ) 0) nil
                    (is-prime x (+ i 1)))
                t))))

(defun prime-factors-helper (x n)
   (if (is-prime x) (list x) 
        (if (is-prime n) 
            (if (and (= (mod x n) 0) (<= n (/ x 2)))
                (append (list n) (prime-factors-helper (/ x n) (+ 1 n)))
                (prime-factors-helper x (+ 1 n)))       
            (prime-factors-helper x (+ 1 n)))))


(defun prime-factors (x)
    (prime-factors-helper x 2)) 

CL-USER 44 : 5 > (prime-factors 66)
(2 3 11)
接下来,我们使用
cond
降低缩进级别

(append(list foo)bar)
只是
(cons foo bar)

如果
,我们也可以去掉一个

(defun prime-factors-helper (x n)
  (cond ((is-prime x)
         (list x))
        ((and (is-prime n)
              (= (mod x n) 0)
              (<= n (/ x 2)))
         (cons n (prime-factors-helper (/ x n) (+ 1 n))))
        (t (prime-factors-helper x (+ 1 n)))))
有一个问题:解决它!

正如你所看到的,还有一个问题……当我们计算8的因子时,我不得不从一个无休止的循环中中断代码

CL-USER 51 > (test)

(2 T (* 2)) 
(3 T (* 3)) 
(4 T (* 2 2)) 
(5 T (* 5)) 
(6 T (* 2 3)) 
(7 T (* 7)) 
Break.
  1 (continue) Return from break.
  2 (abort) Return to top loop level 0.
但这个问题很容易解决,可以作为一种练习

回复。

当您在LispWorks中有这样的提示时

CL-USER 44 : 5 > 
这意味着你有五个(!)级的深度休息

通过输入
:top
命令到达顶级repl的时间:

CL-USER 44 : 5 > :top

CL-USER 45 >

关于代码的一些一般性评论:

(defun is-prime (x &optional (i 2))
    (if (= x 1) nil
        (if (or (= x 2) (= x 3)) t
            (if (<= i (sqrt x))
                (if (= (mod x i ) 0) nil
                    (is-prime x (+ i 1)))
                t))))

(defun prime-factors-helper (x n)
   (if (is-prime x) (list x) 
        (if (is-prime n) 
            (if (and (= (mod x n) 0) (<= n (/ x 2)))
                (append (list n) (prime-factors-helper (/ x n) (+ 1 n)))
                (prime-factors-helper x (+ 1 n)))       
            (prime-factors-helper x (+ 1 n)))))


(defun prime-factors (x)
    (prime-factors-helper x 2)) 

CL-USER 44 : 5 > (prime-factors 66)
(2 3 11)
接下来,我们使用
cond
降低缩进级别

(append(list foo)bar)
只是
(cons foo bar)

如果
,我们也可以去掉一个

(defun prime-factors-helper (x n)
  (cond ((is-prime x)
         (list x))
        ((and (is-prime n)
              (= (mod x n) 0)
              (<= n (/ x 2)))
         (cons n (prime-factors-helper (/ x n) (+ 1 n))))
        (t (prime-factors-helper x (+ 1 n)))))
有一个问题:解决它!

正如你所看到的,还有一个问题……当我们计算8的因子时,我不得不从一个无休止的循环中中断代码

CL-USER 51 > (test)

(2 T (* 2)) 
(3 T (* 3)) 
(4 T (* 2 2)) 
(5 T (* 5)) 
(6 T (* 2 3)) 
(7 T (* 7)) 
Break.
  1 (continue) Return from break.
  2 (abort) Return to top loop level 0.
但这个问题很容易解决,可以作为一种练习

回复。

当您在LispWorks中有这样的提示时

CL-USER 44 : 5 > 
这意味着你有五个(!)级的深度休息

通过输入
:top
命令到达顶级repl的时间:

CL-USER 44 : 5 > :top

CL-USER 45 >

这意味着你的递归没有停止。你似乎停止递归的唯一时间是当x为素数时。如果这种情况永远不会发生,递归将永远继续。你测试过
是素数
以确保它正确吗?@Carcigenicate是的,我测试过。是的correct@Carcigenicate这不是
is prime
函数。我定义了它但是我仍然有完全相同的问题。请检查新的更新,我在其中添加了
is prime
函数的新定义,然后您需要找出递归没有停止的原因。
(prime factors 512)
也可能“太大”使用非优化递归解决的问题。@Carcigenicate我解决了它。实际上它不仅适用于512。它适用于2的所有倍数。在条件
(if(AND(=(mod x n)0)(
如果数字是2的倍数,它将永远不会进入此条件,即使它必须进入此条件。原因是我放置
这意味着您的递归没有停止。您似乎唯一停止递归的时间是当x为素数时。如果从未发生,递归将永远继续。您是否测试了
is prime
以确保它正确ct?@Carcigenicate是的,我测试过了,是的correct@Carcigenicate这不是
is prime
函数。我对它进行了不同的定义,但仍然存在完全相同的问题。请检查我将
is prime
函数的新定义放在哪里的新更新,然后您需要找出递归没有停止的原因。
(素因子512)
也可能是一个“太大”的问题,无法使用非优化递归来解决。@Carcigenicate我解决了它。实际上,它不仅适用于512。它适用于所有2的倍数。在条件
下(if(AND(=(mod x n)0)(
如果数字是2的倍数,它将永远不会进入这种状态,即使它必须进入这种状态。原因是我写了
谢谢你的评论。我已经解决了2的倍数的问题,我只是忘了发布它。但是,我发现了另一个优化问题。你能在我的帖子中检查我的新问题吗。@Benz:m提出一个新问题,不要添加到现有问题上。我刚刚提出了一个新问题。你能看一下吗。谢谢你的评论。我已经解决了2的倍数问题,只是忘了发布。但是,我发现了另一个优化问题。你能在我的帖子中检查我的新问题吗。@Benz:提出一个新问题,不要添加到exis中我刚看了。你能看一下吗。