2012-10-11 16 views
0

我寫兩個程序一個是取出allButLast,另一個是取出secondcond。會員功能不能在cons結構中工作

我最初使用成員函數來確定是否有更多的X落後。

我嘗試了一些資料後,發現:

如果第一個參數是一個符號,他們兩人的工作!

但是,如果它是cons結構,它們都會失敗。

1.// `(a b) `((b b)(a b)(b c)(a b)) ==> `((b b)(b c)(a b)) 

(defun takeoutAllButLast (X L) 
(cond ((null L) nil) 
     ((equal X (first L)) 
      (if (member X (rest L)) 
       (takeoutAllButLast X (rest L)) 
       L)) 
     (t (cons (first L) (takeoutAllButLast X (rest L)))) 
) 
) 

2.//`(a b) `((a b)(b b)(a b)(b c)(a b)) ==> `((a b)(b b)(b c)(a b)) 
(defun takeoutSecondLast (X L) 
(cond ((null L) nil) 
     ((equal X (first L)) 
      (if (member X (rest (member X (rest L)))) 
    (cons (first L) (takeoutSecondLast X (rest L))) 
    (rest L) 
      ) 
    ) 
    (t (cons (first L) (takeoutSecondLast X (rest L)))) 
) 

我想問的是如何確定是否還有一個因素是X的背後,可以像成員函數中使用?

爲什麼成員函數不能用來比較cons結構?

Thx爲你閱讀我的問題!

回答

2

member默認使用eql作爲其相等謂詞。這在符號,數字和其他一些事情上運作良好(即(eq 'a 'a)總是如此,(let ((cons (cons 'a 'a))) (eql cons cons))總是如此,但(eql (cons 'a 'a) (cons 'a 'a))幾乎從未如此)。

您可以使用關鍵字:test通過替代平等檢查,以member,如果你使用#'equal,你會(可能)你想要得到什麼。

如果你想打電話member與檢查foo定製的平等,簡單地做:

(member thing-to-check-for the-list-to-check :test #'foo) 
+0

你能給一個例子,一個平等檢查傳遞給會員嗎?謝謝。 –

+2

試試(會員X(其餘L):test#'等於) – ckb

+0

非常感謝!有用! –