2010-10-12 26 views
4

我在從列表中提取列表時遇到問題。提取列表中的列表

 
(defun delete (a l) 
    (cond 
     ((null l) nil) 
     ((eq (car l) a) (delete a (cdr l))) 
     (t (cons (car l) (delete a (cdr l))))))

它刪除無論是「A」在列表L,但如果L包含另一個列表的和是在內部列表,然後我的程序不能在內部列表內到達。

+4

不要將其命名你的函數刪除。這個名字已經被Common Lisp用於內置函數。 – 2010-10-12 05:01:40

+4

默認的相等測試也應該是EQL而不是EQ。 – 2010-10-12 05:03:02

回答

5

不僅有一種可能的解決方案,但我會保持接近你的代碼。由於這是功課,我不會給你一個工作答案,但我會盡力給你一些想法的東西,並給出詳細的指示:

試着瞭解你的代碼的作用和你真正想要的東西這樣做:

(defun remove-all (a l) 
    (cond ((null l) nil) 
     ((eql (car l) a) (delete a (cdr l))) 
     (t (cons (car l) (delete a (cdr l)))))) 

(更名爲remove-all因爲delete已被使用,並以理智的方式重新縮進。)

對於平面列表,代碼似乎工作;但如何嵌套列表?讓我們看一個簡單的例子:

  1. 如果您評估(remove-all 1 '((1)))會發生什麼?
  2. 你想爲那個輸入發生什麼?
  3. 你怎麼實現它?

讓我們一起來看看:

  1. 會發生什麼:

    • 列表並不null,去
    • careq1
    • '(1)獲得cons ed (remove-all '()),產生'((1))

    所以,它沒有認識到car本身應查找匹配的元素的列表。問題似乎在第一步和第二步之間。

  2. 應該怎樣做:

    • 檢查,如果car也是一個列表
    • 如果是的話,就可以調用remove-all
    • 然後,cons結果爲cdr,這也需要(提示:但只有如果有東西給cons
  3. 究竟如何?

    • 添加cond條款,不低於2中提到的事情 - 左功課
3

您需要另一個子句來測試項目是否爲列表,以及何時將true遞歸到子列表中。