0

だから私は関数がリストを取り、それを元に戻すようにしようとしていますが、RPLACA/ RPLACD/をどのように使用するのかわかりませんNONC。基本的に reverse と同じことを行いますが、元のリストのコンス ノードを使用し、新しいコンス ノードを割り当てません。私がこれまでに持っているのは

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

2 に答える 2

0

したがって、潜在的なリスト引数は(1 2). 引数はアドレス #A のリストに対するもので、次のようになると想像できます。

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

コンスごとに、をcdr前の に設定する前にローカル変数格納を作成します。これは最初の では nil です。現在が完了し、結果が前の. この例の結果は次のようになります。cdrconsconsconsnilcons

#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 <??> <??>))))
于 2015-02-18T21:09:36.737 に答える
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) ))
于 2015-02-26T16:26:53.977 に答える