2015-04-18 169 views
-1

我一直在使用常見的LISP進行數週的調試,主要嘗試練習遞歸。我想要做的是有一個函數常見的LISP函數,用於刪除列表中每個子列表的第n個位置上的元素

(defun rem (n l) 
    ; code here 
) 

,其中n爲總是一個非負整數,λ可以是原子/列表/空。該函數刪除的第n個元素(一個基於索引):

  • 列表(L)本身

  • 任何級別的子列表的原始列表包含

我估計使用刪除第n會使這項任務小菜一碟,但我還沒有取得任何成功。

任何答案/實際代碼將不勝感激。謝謝!

回答

1

你沒有說如果你想要remove功能或delete功能。我會在這裏做非破壞性的版本。

您可以製作一個列表的remove-nth,方法是在索引之前創建所有元素的新列表,然後使用要刪除的cons的尾部以共享盡可能多的結構。這是一個使用subseq,nconcnthcdr的實現來展示它是多麼容易,沒有遞歸。

(defun remove-nth (n list) 
    (nconc (subseq list 0 n) (nthcdr (1+ n) list))) 

(defparameter *test* (list 0 1 2 3 4 5 6)) 
(remove-nth 3 *test*) ; ==> (0 1 2 4 5 6) 
(remove-nth 0 *test*) ; ==> (1 2 3 4 5 6) 

遞歸函數會是這個樣子:

(defun remove-nth-rec (n list) 
    (assert (not (null list))) 
    (if (zerop <??>) 
     <??> 
     (cons <??> (remove-nth-rec <??> <??>)))) 

可以使功能,這是否對每個子表遞歸了。我會用mapcar做到這一點:

(defun remove-all-nth (n lol) 
    (mapcar (lambda (x) (remove-nth n x)) lol)) 

(remove-all-nth 0 '((a b c) (0 1 2) (I II III))) ; ==> ((b c) (1 2) (II III)) 

遞歸函數會是這個樣子:

(defun remove-all-nth-rec (n list) 
    (if (null <??>) 
     nil 
     (cons (remove-nth-rec n <??>) 
      (remove-all-nth-rec n <??>)))) 
相關問題