我编写了一个名为my_rotate
的函数,它从用户那里获取一个数字并创建一个最多五个数字的列表。然后,my_rotate
弹出列表的第一个元素并将其添加到列表的末尾。关于我如何写my_rotate
以接收另一个号码n
并根据用户输入的号码n
轮换列表的任何建议。
示例:
> (my_rotate 1 2)
输出:
(3 4 5 1 2)
这是我到目前为止所做的:
(defun my_rotate (y)
(append (loop for i from (+ 1 y) to (+ 4 y) collect i)
(list y)))
答案 0 :(得分:1)
这里的功能。 我创建了两个列表然后将它们连接起来。
(defun my-rotate (length shift)
"Return a list of given LENGTH, rotated by SHIFT."
(nconc
(loop for i from (1+ shift) to (- length shift -2) collect i)
(loop for i from 1 to shift collect i)))
(my-rotate 7 2)
==> (3 4 5 6 7 1 2)
请注意,由于两个loop
生成了fresh个列表,因此我使用nconc
代替append
。
但是,如果要旋转现有列表,则需要执行其他操作:
(defun rotate-list (list shift)
"Rotate the given LIST by the specified SHIFT."
(let ((len (length list)))
(setq shift (mod shift len)) ; handle circular shifts
(append (nthcdr (- len shift) list)
(butlast list shift))))
(rotate-list '(1 2 3 4 5 6) 2)
==> (5 6 1 2 3 4)
(rotate-list '(1 2 3 4 5 6) 20)
==> (5 6 1 2 3 4) ; same because 20 = 2 mod 6
(rotate-list '(1 2 3 4 5 6) 0)
==> (1 2 3 4 5 6) ; unchanged
请注意nthcdr
点在原始列表中,因此我们必须使用append
来避免修改参数。
另请注意,我们会扫描list
参数两次(一次在nthcdr
,一次在butlast
)。
如果您的列表很大,并且分析显示此函数是瓶颈,您可能想要使用循环重写(这种情况是不太可能的,我已经后悔浪费了我写这篇文章的时间)。