2017-03-06 3 views
0

これは私のリスプコードです。lispのスワップリスト要素

(defun f (lst) 
       (append (subst (last lst) (first lst) (car lst)) 
       (subst (first lst) (last lst) (cdr lst))) 
       ) 

(F「(B CはD))

このコードの出力である(D B C。A)

機能がうまく機能し、それが原因のシンボルの終了していません。 make(D B C A)をシンボルなしで作成します。

どうすれば修正できますか?それとも良い方法がありますか?

私は助けていただければ幸いです。

+0

コードを適切に書式設定して、機能が想定していることを説明してください。 – sds

答えて

2

あなたは、あなたが何かlike thisを行うことを意味していることをtry using rotatefしたと仮定すると:

? (setf lst '(a b c d)) 
(A B C D) 
? lst 
(A B C D) 
? (rotatef (nth 0 lst) (nth (- (length lst) 1) lst)) 
;Compiler warnings : 
; In an anonymous lambda form at position 0: Undeclared free variable LST (3 references) 
NIL 
? lst 
(D B C A) 
1

あなたが最初と最後の要素を交換したいと仮定すると、ここでそれを行う実装です。これはリストを3回トラバースして2回コピーします。これよりもはるかにうまくいく可能性がありますが、合理的に悪意を持っているわけではありません(特にrotatefの素朴な実装は、一度rotatefは破壊的であるので、あなたは、リストの最初のコピーを必要とするよう):

(defun swapify (list) 
    ;; swap the first and last elements of list 
    (if (null (rest list)) 
     list 
     (cons (first (last list)) ; 1st traversal 
      (append (butlast (rest list)) ; 2nd and third traversals 
        (list (first list)))))) 

そして、ここでは正確に一度リストを横断よこしまな実装です。これは、テールコールの削除に依存します。より簡単なループを使用するバージョンはかなり明白です。

(defun swapify (list) 
    ;; return a copy of list with the first and last elements swapped 
    (if (null (rest list)) 
     list 
     (let ((copy (cons nil nil))) 
     (labels ((walk (current tail) 
        (if (null (rest tail)) 
         (progn 
         (setf (first copy) (first tail) 
           (rest current) (cons (first list) nil)) 
         copy) 
         (progn 
         (setf (rest current) (cons (first tail) nil)) 
         (walk (rest current) (rest tail)))))) 
      (walk copy (rest list)))))) 
関連する問題