Loops lisp中的偶数斐波那契数求和

Loops lisp中的偶数斐波那契数求和,loops,lisp,common-lisp,Loops,Lisp,Common Lisp,我刚刚开始学习Lisp,我正在解决一些Project Euler问题。我被困在一个你把偶数斐波那契数加在一个最大数下面的问题上。我尝试过的事情都会遵循。我读过,但我仍然不知道为什么我的两种方法都不管用 CL-USER> (defun sum-even-fibs (max) (do ((curr 0 next) (next 1 (+ curr next)) (sum 0 (if (evenp curr)

我刚刚开始学习Lisp,我正在解决一些Project Euler问题。我被困在一个你把偶数斐波那契数加在一个最大数下面的问题上。我尝试过的事情都会遵循。我读过,但我仍然不知道为什么我的两种方法都不管用

CL-USER> (defun sum-even-fibs (max)
           (do ((curr 0 next)
                (next 1 (+ curr next))
                (sum  0 (if (evenp curr) (+ sum curr))))
               ((> max curr) sum)))
SUM-EVEN-FIBS
CL-USER> (sum-even-fibs 10)
0


CL-USER> (defun sum-even-fibs (max)
           (let ((sum 0))
             (do ((curr 0 next)
                  (next 1 (+ curr next)))
                 ((> max curr))
               (if (evenp curr) 
                   (setq sum (+ sum curr))))
             (format t "~d" sum)))
SUM-EVEN-FIBS
CL-USER> (sum-even-fibs 10)
0
NIL

只要
max
大于
sum
,就会终止
do
循环,这发生在第一次迭代时

将该
切换为
后,当
当前值
ent Fibonacci数大于
最大值
imum值时终止,并将else大小写添加到
if
表达式中,这样当
(evenp curr)
为false时,值为
总和

(defun sum-even-fibs (max)
  (do ((curr 0 next)
       (next 1 (+ curr next))
       (sum 0 (if (evenp curr) (+ sum curr) sum)))
      ((> curr max) sum)))

循环指令有许多很好的特性:

(loop with a = 0 and b = 1 
      while (< a 4000000) 
      when (evenp a)
      sum a
      do (psetf a b b (+ a b)))
(a=0和b=1的循环
而(<400万澳元)
什么时候(晚上)
求和
do(psetf a b(+a b)))

请参见通用Lisp HyperSpec中arbautjc答案的“更好”版本:

(loop for a = 0 then b and b = 1 then (+ a b) 
      while (< a 4000000) 
      when (evenp a) sum a)
(a=0然后是b,b=1然后是(+AB)的循环
而(<400万澳元)
当(偶数a)和a)

谢谢!我知道在第一次迭代中,求值顺序会有问题,但我想确保函数确实会首先执行某些操作。作为lisp n00b,我希望看到正确的代码。我遇到的问题是:我可以做一个循环,我可以做if,但我一直在(a)将sum初始化为0,(b)显示结果。谢谢@奥利,我已经发布了修改后的代码。它几乎和原作一样,但有我提到的变化。关于
do/do*
的评论只是警告;对于这个问题,
do
是正确的。谢谢。通过更多的练习,你是否能更好地直觉在不同的情况下(Do、loop、dolist、dotimes等)使用哪种循环结构?@lightlike-Yes。(尽管我发现答案是典型的
loop
,有时是
mapcar
,偶尔是
dolist
.YMMV,当然,但我很久没有使用
dotimes
do
)。