Printing 在公共Lisp中打印前N个素数

Printing 在公共Lisp中打印前N个素数,printing,numbers,lisp,primes,clisp,Printing,Numbers,Lisp,Primes,Clisp,我正在制作一个公共Lisp函数来打印前N个素数。到目前为止,我已经成功地编写了以下代码: ;globals (setf isprime 1) ;if 1 then its a prime, 0 if not. (setf from 1) ;start from 1 (setf count 0) ;should act as counter to check if we have already ; N primes printed ;fun

我正在制作一个公共Lisp函数来打印前N个素数。到目前为止,我已经成功地编写了以下代码:

;globals 
(setf isprime 1) ;if 1 then its a prime, 0 if not.
(setf from 1)    ;start from 1
(setf count 0)   ;should act as counter to check if we have already 
                 ;    N primes printed

;function so far.
(defun prime-numbers (to)
  (if (> count to) nil(progn
      (is-prime from from)
      (if (= isprime 1) (print from)(setf count (+ count 1)))
      (setf isprime 1)
      (setf from (+ from 1))
      (prime-numbers to)))
  (if (>= count to)(setf count 0) (setf from 1)))  

;code to check if a number is prime    
(defun is-prime(num val)
  (if (< num 3) nil 
    (progn
      (if (= (mod val (- num 1)) 0) (setf isprime 0))
      (is-prime (- num 1) val))))

很好。但是在最后输出一个NIL。

首先,这里根本不需要使用globals

使用真/假返回值。这将允许您的
is prime
函数类似于:

(defun is-prime (n)
  (cond ((= 2 n) t) ;; Hard-code "2 is a prime"
        ((= 3 n) t) ;; Hard-code "3 is a prime"
        ((evenp n) nil) ;; If we're looking at an even now, it's not a prime
        (t ;; If it is divisible by an odd number below its square root, it's not prime
           (loop for i from 3 to (isqrt n) by 2
                 never (zerop (mod n i))))))
这样,函数就不依赖于任何外部状态,也没有任何东西会混淆任何东西

其次,您看到的最后一个
1
可能是函数的返回值

要检查这一点,请尝试: (progn(质数10)nil)

第三,重新编写
素数
函数以避免使用全局变量


第四,切勿使用或创建全局变量,请使用或。在全局(实际上是“特殊”)变量上使用
*耳罩*
也是一种很好的方式(大多数情况下,但有些人不同意)。

首先,这里根本不需要使用全局变量

使用真/假返回值。这将允许您的
is prime
函数类似于:

(defun is-prime (n)
  (cond ((= 2 n) t) ;; Hard-code "2 is a prime"
        ((= 3 n) t) ;; Hard-code "3 is a prime"
        ((evenp n) nil) ;; If we're looking at an even now, it's not a prime
        (t ;; If it is divisible by an odd number below its square root, it's not prime
           (loop for i from 3 to (isqrt n) by 2
                 never (zerop (mod n i))))))
这样,函数就不依赖于任何外部状态,也没有任何东西会混淆任何东西

其次,您看到的最后一个
1
可能是函数的返回值

要检查这一点,请尝试: (progn(质数10)nil)

第三,重新编写
素数
函数以避免使用全局变量


第四,切勿使用或创建全局变量,请使用或。在您的全局(实际上是“特殊”)变量上使用
*耳罩*
也是一种很好的方式(大多数情况下,但有些人不同意)。

要详细介绍Vatines,请回答:

可以使用相同的算法重写
素数
函数,但避免使用全局变量

(defun prime-numbers (num &optional (from 2))
   (cond ((<= num 0) nil)
         ((is-prime from) (cons from (prime-numbers (1- num) (1+ from))))
         (t (prime-numbers num (1+ from)))))

要详细介绍梵蒂冈,请回答:

可以使用相同的算法重写
素数
函数,但避免使用全局变量

(defun prime-numbers (num &optional (from 2))
   (cond ((<= num 0) nil)
         ((is-prime from) (cons from (prime-numbers (1- num) (1+ from))))
         (t (prime-numbers num (1+ from)))))

请修复代码格式并删除
defun
sCLISP前面的反勾号。sCLISP是编程语言“Common Lisp”的一种实现。我已重新缩进了您的第一个代码,但未触及第二个代码。您的缩进不正确。请修复代码格式并删除
defun
sCLISP前面的反勾号。sCLISP是编程语言“Common Lisp”的一种实现。我已重新缩进了您的第一个代码,但未触及第二个代码。您在那里有一些不正确的缩进。您可以在
循环中使用
始终
,而不是
返回@sds True。我在愤怒中写循环已经有几年了,而从
返回的
几乎是触手可及的。@sds是用
从不
重写的。谢谢你!。但我仍然没有所需的输出。除了环球。我的素数有什么问题吗?@binaryjc我实际上认为使用globals是造成你的问题的原因。使用全局状态在函数之间进行通信接近使代码不工作的最佳方法。您可以在
循环中使用
始终
,而不是
返回@sds True。我在愤怒中写循环已经有几年了,而从
返回的
几乎是触手可及的。@sds是用
从不
重写的。谢谢你!。但我仍然没有所需的输出。除了环球。我的素数有什么问题吗?@binaryjc我实际上认为使用globals是造成你的问题的原因。使用全局状态在函数之间进行通信接近使代码不工作的最佳方法。