2011-10-26 113 views
2

我有一個稱爲修改列表的函數實現如下所示,但它只適用於頂級列表。在LISP中修改/替換

(defun modify-list (old new a-list) 
    (cond 
    ((null a-list) nil) 
    ((eql (car a-list) old) (cons new (modify-list old new (cdr a-list)))) 
    (T (cons (car a-list)(modify-list old new (cdr a-list)))))) 

CL-USER 16:6>(修改列表 '一個' X「(P A d克℃的)) (P X d克碳X)< - GOOD!

CL-USER 17:6>(修改列表'a'x'(p a d(g a)c a)) (P X D(G A)C X)< ----不好!

任何人都可以幫助我使這個函數在嵌套列表上工作嗎?

回答

3

爲什麼不能在更高的水平上工作?這將使得代碼更簡單...

(defun modify (old new x) 
    (cond 
    ((eq x old) new) 
    ((listp x) 
    (mapcar (lambda (y) (modify old new y)) x)) 
    (t x))) 

基本上代替假設x必須是一個列表(實際上是一個樹),你只返回new如果xold,遞歸映射如果它是一個列表或者否則返回x不變...

這種方法也(modify 'a 'x 'a) --> X(和IMO似乎是正確的)。

+0

這就是爲什麼我愛堆棧溢出...總是有用的感謝 – user1013905

0

這裏有一個想法:

(defun modify-list (old new a-list) 
    (cond ((null a-list) nil) 
     ((not (listp (car a-list))) 
     (if (eql (car a-list) old) 
      (cons new (modify-list old new (cdr a-list))) 
      (cons (car a-list) (modify-list old new (cdr a-list))))) 
     (T (cons (modify-list old new (car a-list)) 
       (modify-list old new (cdr a-list)))))) 

我沒有訪問到LISP解釋器(任何人都可以驗證上面的過程,好嗎?),所以你必須先測試一下吧!