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是此处代码段中引入的名称。