我们今天刚刚在课堂上介绍了循环,我有一些我需要做的事情。简而言之,我必须使用循环而不是递归来构建列表。我似乎在这里遇到了绊脚石。对于这个例子,我们需要做一个简单的倒计时。该函数接受一个参数,然后返回一个小于或等于初始参数的所有正整数的列表。 (倒计时5)=> (5 4 3 2 1)
由于某种原因,我很难获得循环。我们谈到的是Loop,Do,Dotimes和Dolist。我已经尝试了几个循环并且总是得到类似的结果。
(defun countdown (num)
(cond ((= num 0) nil)
(T (let* ((list nil))
(loop
(if (= num 0) (return list)
(setf list (cons list num)))
(setf num (- num 1)))))))
我的输出显示如下:
(((((NIL . 5) . 4) . 3) . 2) .1)
更新:我已经解决了这个问题。显然我需要在cons
中颠倒顺序,因此num
在list
之前。有人关心解释这个吗?我以为你把列表放在第一位,然后你把第二位放到最后。至少,这就是我到目前为止一直没有使用它的方式。
答案 0 :(得分:4)
cons
(及其原因)你在an answer中写道(因为它要求提供更多信息,或许应该是评论):
我已经解决了这个问题。显然我需要改变顺序 缺点,所以num在列表之前。有人关心解释这个吗?一世 以为你把列表放在第一位,然后你把第二位放在第二位 添加到它的末尾。至少,到目前为止我是如何使用它的 没有问题。
该功能在HyperSpec中有明确记录:Function CONS。文档中的示例显示,例如,
(cons 1 (cons 2 (cons 3 (cons 4 nil)))) => (1 2 3 4)
(cons 'a (cons 'b (cons 'c '()))) => (A B C)
(cons 'a '(b c d)) => (A B C D)
甚至是笔记
如果object-2是一个列表,那么cons可以被认为是生成一个新的列表,就像它一样,但是前面有object-1。
阅读14.1.2 Conses as Lists也可能有所帮助,其中包括:
列表是一系列的汇总,其中每个利弊的汽车是列表的一个元素,每个利弊的cdr是链中的下一个链接或终止原子。
loop
这里的许多答案都向您指出循环表单包含一种特殊的迭代语言。这是真的,但也可以按照您使用它的方式使用。这种方式称为简单循环:
6.1.1.1.1 Simple Loop
一个简单的循环形式是一个只包含化合物的循环形式 形式。每个表格依次从左到右进行评估。当。。。的时候 最后一个表格已被评估,然后再次评估第一个表格, 等等,在一个永无止境的循环中。一个简单的循环形式建立一个 隐式块名为nil。执行一个简单的循环即可 通过显式将控制转移到隐式块来终止 (使用返回或返回)或到某些出口点之外 阻止(例如,使用throw,go或return-from)。
简单循环可能不像循环使用循环提供的更好的功能那样常见,但是如果你刚刚在课堂上介绍过这个,那么你可能还没有。但其他答案确实提供了一些很好的例子。
答案 1 :(得分:2)
如果您谈到常见的lisp loop,您的倒计时可能如下所示:
(defun countdown (from-number)
(loop :for x :from from-number :downto 1 :collect x))
CL-USER> (countdown 10)
(10 9 8 7 6 5 4 3 2 1)
答案 2 :(得分:1)
使用loop
,它有自己的“特殊用途语言”,看起来不像Lisp:
(defun countdown (n)
(loop
for i from n downto 1
collect i))
或使用do
:
(defun countdown (n)
(do ((i 1 (1+ i))
(res nil (cons i res)))
((> i n) res)))
见here,特别是第7章和第22章。