CommonLisp:循环列表对
我有一个列表,它的长度可以被2整除,我在寻找类似于这个问题的答案:CommonLisp:循环列表对,lisp,common-lisp,sbcl,Lisp,Common Lisp,Sbcl,我有一个列表,它的长度可以被2整除,我在寻找类似于这个问题的答案: (loop for (a b) on lst while b collect (+ a b)) 但是,元素之间存在重叠: (1 2 3 4 5) -> (3 5 7 9) 添加1和2,然后添加2和3,以此类推 我有一个类似(1234)的列表,我正在寻找类似 ((1 2) (3 4)) 作为输出。有没有办法使循环正确地跨过列表? 另一种解决方案。类似的解决方案应该可以: (let ((list '(1 2
(loop for (a b) on lst while b
collect (+ a b))
但是,元素之间存在重叠:
(1 2 3 4 5) -> (3 5 7 9)
添加1和2,然后添加2和3,以此类推
我有一个类似(1234)
的列表,我正在寻找类似
((1 2) (3 4))
作为输出。有没有办法使循环正确地跨过列表?
另一种解决方案。类似的解决方案应该可以:
(let ((list '(1 2 3 4)))
(loop :for (a b) :on list :by #'cddr :while b
:collect (cons a b)))
还有一个更详细的变体:
(let ((list '(1 2 3 4)))
(loop :for a :in list :by #'cddr
:for b :in (cdr list) :by #'cddr
:collect (cons a b)))
使用包的另一种方法。 另见Richard C.Waters的文章 安装程序 代码
将
列表的内容扫描为“序列”
M=2和N=2时的块: 此函数的作用是分解输入序列项 分成(可能重叠的)长度为m的块。起始位置 连续块的数量相差n。输入m和n必须同时为 正整数 更准确地说,chunk
产生(区块2(扫描)(1234))
和#Z(13)
#Z(24)
,生成一系列对,就像在这些序列的每个
和奇数
元素上并行映射偶数
所做的那样(列出奇偶)
- 最后,
将结果收集为列表
(LET* ((#:OUT-1120 LIST))
(LET (#:ELEMENTS-1117
(#:LISTPTR-1118 #:OUT-1120)
(#:COUNT-1113 0)
#:CHUNK-1114
#:CHUNK-1115
#:ITEMS-1123
(#:LASTCONS-1106 (LIST NIL))
#:LST-1107)
(DECLARE (TYPE LIST #:LISTPTR-1118)
(TYPE FIXNUM #:COUNT-1113)
(TYPE CONS #:LASTCONS-1106)
(TYPE LIST #:LST-1107))
(SETQ #:COUNT-1113 1)
(SETQ #:LST-1107 #:LASTCONS-1106)
(TAGBODY
#:LL-1124
(IF (ENDP #:LISTPTR-1118)
(GO SERIES::END))
(SETQ #:ELEMENTS-1117 (CAR #:LISTPTR-1118))
(SETQ #:LISTPTR-1118 (CDR #:LISTPTR-1118))
(SETQ #:CHUNK-1114 #:CHUNK-1115)
(SETQ #:CHUNK-1115 #:ELEMENTS-1117)
(COND ((PLUSP #:COUNT-1113) (DECF #:COUNT-1113) (GO #:LL-1124))
(T (SETQ #:COUNT-1113 1)))
(SETQ #:ITEMS-1123
((LAMBDA (ODD EVEN) (LIST ODD EVEN)) #:CHUNK-1114 #:CHUNK-1115))
(SETQ #:LASTCONS-1106
(SETF (CDR #:LASTCONS-1106) (CONS #:ITEMS-1123 NIL)))
(GO #:LL-1124)
SERIES::END)
(CDR #:LST-1107)))
或
这可能会变得非常慢,是否有一个非循环的宏变量可能更快?@cheshirecatalyst抱歉,不知道你的意思。它应该和其他循环选项(dolist、mapcar等)一样快,使用“:by”关键字不会使循环变慢,实际上它会减少两倍的步骤。
(defun pairs (list)
(collect 'list
(mapping (((odd even) (chunk 2 2 (scan 'list list))))
(list odd even))))
(LET* ((#:OUT-1120 LIST))
(LET (#:ELEMENTS-1117
(#:LISTPTR-1118 #:OUT-1120)
(#:COUNT-1113 0)
#:CHUNK-1114
#:CHUNK-1115
#:ITEMS-1123
(#:LASTCONS-1106 (LIST NIL))
#:LST-1107)
(DECLARE (TYPE LIST #:LISTPTR-1118)
(TYPE FIXNUM #:COUNT-1113)
(TYPE CONS #:LASTCONS-1106)
(TYPE LIST #:LST-1107))
(SETQ #:COUNT-1113 1)
(SETQ #:LST-1107 #:LASTCONS-1106)
(TAGBODY
#:LL-1124
(IF (ENDP #:LISTPTR-1118)
(GO SERIES::END))
(SETQ #:ELEMENTS-1117 (CAR #:LISTPTR-1118))
(SETQ #:LISTPTR-1118 (CDR #:LISTPTR-1118))
(SETQ #:CHUNK-1114 #:CHUNK-1115)
(SETQ #:CHUNK-1115 #:ELEMENTS-1117)
(COND ((PLUSP #:COUNT-1113) (DECF #:COUNT-1113) (GO #:LL-1124))
(T (SETQ #:COUNT-1113 1)))
(SETQ #:ITEMS-1123
((LAMBDA (ODD EVEN) (LIST ODD EVEN)) #:CHUNK-1114 #:CHUNK-1115))
(SETQ #:LASTCONS-1106
(SETF (CDR #:LASTCONS-1106) (CONS #:ITEMS-1123 NIL)))
(GO #:LL-1124)
SERIES::END)
(CDR #:LST-1107)))
CL-USER 156 > (loop with list = '(1 2 3 4)
while list
collect (loop repeat 2
while list
collect (pop list)))
((1 2) (3 4))
CL-USER 166 > (loop with list = '(1 2 3 4 5 6)
while (and list (cdr list))
collect (loop repeat 2 collect (pop list)))
((1 2) (3 4) (5 6))
CL-USER 167 > (loop with list = '(1 2 3 4 5 6 7)
while (and list (cdr list))
collect (loop repeat 2 collect (pop list)))
((1 2) (3 4) (5 6))