LISP:使用RPLACA / RPLACD / NCONC在LISP中反转列表

时间:2015-02-17 04:18:17

标签: lisp land-of-lisp

所以我试图让一个函数列入一个列表并反转它,但我不确定如何使用RPLACA / RPLACD / {{ 1}}。基本上与反向相同,但它使用原始列表的cons节点,并且不分配任何新的cons节点。到目前为止我所拥有的是

NONC

2 个答案:

答案 0 :(得分:0)

因此潜在的列表参数为(1 2)。我们可以想象参数是地址#A的列表,它看起来像这样:

#A=(1 . #B)
#B=(2 . nil) 

对于每个缺点,我们创建存储cdr的局部变量,然后将cdr设置为前一个cons,第一个cons为零。当前cons nil完成后,结果就是之前的cons。我们的例子的结果是:

#A=(1 . nil)
#B=(2 . #A) 

您需要的唯一变异函数是rplacd,因为唯一改变的是cdr。该函数可能如下所示:

(defun nreverse (list)
  (labels ((aux (list prev)
             (if (endp list)
                 <??>
                 (let ((next <??>))
                   (rplacd <??> <??>)
                   (aux <??> <??>)))))
    (aux list nil)))

或者,如果你不介意泄漏,你可以这样做:

(defun nreverse (list &optional prev)
  (if (endp list)
      <??>
      (let ((next <??>))
        (rplacd <??> <??>)
        (nreverse <??> <??>))))

答案 1 :(得分:0)

所以我相信这是他们正在寻找的答案:

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) ))