我现在已经乱搞了常见的LISP几周了,大多数都试图练习递归。我想做的是有一个功能
(defun rem (n l)
; code here
)
其中n 总是非负整数,l可以是atom / list / null。该函数删除了第n个元素(基于一个索引):
列表(l)本身
原始列表包含的任何级别子列表
我认为使用删除和 nth 会让这项任务变得轻而易举,但我还没有取得任何成功。
任何答案/实际代码将不胜感激。谢谢!
答案 0 :(得分:1)
您没有说出是否需要remove
功能或delete
功能。我会在这里做非破坏性的版本。
您可以通过在索引之前创建所有元素的新列表来为一个列表创建remove-nth
,然后使用要删除的cons
的尾部来共享尽可能多的结构。以下是使用subseq
,nconc
和nthcdr
的实现,以显示没有递归的情况。
(defun remove-nth (n list)
(nconc (subseq list 0 n) (nthcdr (1+ n) list)))
(defparameter *test* (list 0 1 2 3 4 5 6))
(remove-nth 3 *test*) ; ==> (0 1 2 4 5 6)
(remove-nth 0 *test*) ; ==> (1 2 3 4 5 6)
递归函数看起来像这样:
(defun remove-nth-rec (n list)
(assert (not (null list)))
(if (zerop <??>)
<??>
(cons <??> (remove-nth-rec <??> <??>))))
你也可以递归地在每个子列表上创建这个功能。我用mapcar
:
(defun remove-all-nth (n lol)
(mapcar (lambda (x) (remove-nth n x)) lol))
(remove-all-nth 0 '((a b c) (0 1 2) (I II III))) ; ==> ((b c) (1 2) (II III))
递归函数看起来像这样:
(defun remove-all-nth-rec (n list)
(if (null <??>)
nil
(cons (remove-nth-rec n <??>)
(remove-all-nth-rec n <??>))))