LISP:使用RPLACA/RPLACD/ncoc在LISP中反转列表
因此,我试图让一个函数接受一个列表并在适当的位置反转它,但我不确定如何使用LISP:使用RPLACA/RPLACD/ncoc在LISP中反转列表,lisp,land-of-lisp,Lisp,Land Of Lisp,因此,我试图让一个函数接受一个列表并在适当的位置反转它,但我不确定如何使用RPLACA/RPLACD/NONC。基本上与reverse做相同的事情,但是它使用原始列表的cons节点,并且不分配任何新的cons节点。到目前为止,我得到的是 (defun rip(lst) (cond (( null lst) 0) ((eq (nil) (cdr (last lst))) 1) (((setq x (car (last lst))) (rplaca (car (last
RPLACA
/RPLACD
/NONC
。基本上与reverse做相同的事情,但是它使用原始列表的cons节点,并且不分配任何新的cons节点。到目前为止,我得到的是
(defun rip(lst)
(cond (( null lst) 0)
((eq (nil) (cdr (last lst))) 1)
(((setq x (car (last lst)))
(rplaca (car (last lst)) (car first lst))
(rplaca (car first lst) x)) + 2 rip(butlast(rest lst)))))
所以一个可能的列表参数是
(12)
。我们可以想象,这个论点是针对地址为#A的列表的,它看起来是这样的:
#A=(1 . #B)
#B=(2 . nil)
(defun nreverse (list)
(labels ((aux (list prev)
(if (endp list)
<??>
(let ((next <??>))
(rplacd <??> <??>)
(aux <??> <??>)))))
(aux list nil)))
对于每个cons,在将cdr
设置为前一个cons
之前,我们创建存储cdr
的局部变量,第一个cons
为零。当当前的cons
为nil
时,您的操作完成,结果为上一个cons
。我们示例的结果是:
#A=(1 . nil)
#B=(2 . #A)
唯一需要的变异函数是rplacd
,因为唯一需要更改的是cdr
。该函数可以如下所示:
#A=(1 . #B)
#B=(2 . nil)
(defun nreverse (list)
(labels ((aux (list prev)
(if (endp list)
<??>
(let ((next <??>))
(rplacd <??> <??>)
(aux <??> <??>)))))
(aux list nil)))
(定义nreverse(列表)
(标签((辅助)(列表上)
(如果(endp列表)
(让((下))
(拉丁美洲和加勒比共同体)
(辅助(()))
(辅助列表(无)))
或者,如果您不介意泄漏,您可以这样做:
(defun nreverse (list &optional prev)
(if (endp list)
<??>
(let ((next <??>))
(rplacd <??> <??>)
(nreverse <??> <??>))))
(定义nreverse(列表和可选上一个)
(如果(endp列表)
(让((下))
(拉丁美洲和加勒比共同体)
(nreverse)
所以我相信这就是他们想要的答案:
Recursive:
(define rip (lst)
(if (null lst) nil (nconc (rip (rest lst))(rplacd lst nil))))
Non-Recursive:
(defun rip (lst)
(do ((res nil) (todo (rest lst)(rest lst)))
((null lst) res)
(setf res (rplacd lst res))
(setf lst todo) ))
欢迎来到stackoverflow。听起来你自己也试过写一些代码。你应该把它包括在问题中,即使它是不完整的。它为我们提供了一个起点,表明您做出了努力。到目前为止,我没有使用任何必需的函数。(取消原地倒车(左)(左)(左)(右)(左)(右)(左)(左)(右)(左)(左)(右)(左)(右)(右)(左)(右)(左)(右)(左)(右)(左)(右)(左)(右)(左)(右)(左)(右)(左)(右)(左)(左)(右)(左)(右)(左)(左)(右)(右)(左)(左)(右)(左)(右)(右)(左)(右)(右)(左)(右)(右)(左)(右)(右)(右)(右)(右)(右)(右)(@John你确定你在使用Common Lisp吗?我不认为
递归
或修改
都是该语言中的东西。抱歉,我添加了错误的内容tag@zck:RECURSE是一个宏,例如在Lisp的书中使用。REVING是此处代码段中引入的名称。