Common Lisp中的循环列表

Fed*_*ssa 8 lisp common-lisp circular-list

我正在使用基于CL的音乐创作的可视化编程环境.我正在尝试创建一个函数,当给出时,说3个元素(1 2 3)将返回1,2,3,1,2,3等,每次评估时都有一个数字." Common Lisp a Gentle Introduction "一书简要提到,可以使用尖锐相等的符号创建循环列表,但不会详细介绍如何使用它们.请记住,我可以使用专门为此设计的对象在程序中插入实际的Lisp代码.

Rai*_*wig 14

CL-USER 3 > (defun circular (items)
              (setf (cdr (last items)) items)
              items)
CIRCULAR

CL-USER 4 > (setf *print-circle* t)
T

CL-USER 5 > (circular (list 1 2 3))
#1=(1 2 3 . #1#)
Run Code Online (Sandbox Code Playgroud)

例:

CL-USER 16 > (setf c1 (circular (list 1 2 3)))
#1=(1 2 3 . #1#)

CL-USER 17 > (pop c1)
1

CL-USER 18 > (pop c1)
2

CL-USER 19 > (pop c1)
3

CL-USER 20 > (pop c1)
1
Run Code Online (Sandbox Code Playgroud)

也:

CL-USER 6 > '#1=(1 2 3 . #1#)
#1=(1 2 3 . #1#)
Run Code Online (Sandbox Code Playgroud)

添加了一些CLOS:

(defclass circular ()
  ((items :initarg :items)))

(defmethod initialize-instance :after ((c circular) &rest initargs)
  (setf (slot-value c 'items) (circular (slot-value c 'items))))

(defmethod next-item ((c circular))
  (prog1 (first (slot-value c 'items))
    (setf (slot-value c 'items)
          (rest (slot-value c 'items)))))

CL-USER 7 > (setf circ1 (make-instance 'circular :items (list 1 2 3)))
#<CIRCULAR 40200017CB>

CL-USER 8 > (next-item circ1)
1

CL-USER 9 > (next-item circ1)
2

CL-USER 10 > (next-item circ1)
3

CL-USER 11 > (next-item circ1)
1

CL-USER 12 > (next-item circ1)
2
Run Code Online (Sandbox Code Playgroud)

  • @tsikov:是的,但我希望它在源头上更清晰,而不是依赖于读者的知识. (3认同)

Chr*_*ung 10

Sharpsign Equal-Sign表示法中,它被写为#0=(1 2 3 . #0#).

这是一个从给定参数创建这样一个列表的函数:

(defun circular (first &rest rest)
  (let ((items (cons first rest)))
    (setf (cdr (last items)) items)))
Run Code Online (Sandbox Code Playgroud)

然后,调用(circular 1 2 3)将返回您想要的循环列表.只需使用carcdr无限循环遍历元素即可.

如果你真的想要一个不带参数的迭代器函数并返回每个调用的下一个项目,那么你可以这样做:

(defun make-iter (list)
  (lambda ()
    (pop list)))
Run Code Online (Sandbox Code Playgroud)

  • @ThomasBartscher谢谢!现在已经实施了.(实际上我查看了Rainer的答案,似乎`pop`和我所追求的一样.这就是当Schemer试图写CL时会发生的事情.;-)) (2认同)