使用循环构建列表

时间:2014-09-17 03:25:42

标签: list loops lisp common-lisp cons

我们今天刚刚在课堂上介绍了循环,我有一些我需要做的事情。简而言之,我必须使用循环而不是递归来构建列表。我似乎在这里遇到了绊脚石。对于这个例子,我们需要做一个简单的倒计时。该函数接受一个参数,然后返回一个小于或等于初始参数的所有正整数的列表。 (倒计时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中颠倒顺序,因此numlist之前。有人关心解释这个吗?我以为你把列表放在第一位,然后你把第二位放到最后。至少,这就是我到目前为止一直没有使用它的方式。

3 个答案:

答案 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章。