2013-02-06 60 views
0

我正在Lisp編寫一個程序,將兩個列表中的常用元素放入一個新列表中。這是我的代碼。在列表中,如何通過將列表作爲參數的函數對列表進行修改?

(defun test (a b) 
    (let ((alist nil) (blist nil)) 
    (progn 
     (join a b alist blist) 
     (print blist)))) 

(defun join (a b alist blist) 
    (cond 
    ((and (null a) (null b)) 
    (setf blist (cons alist blist))) 
    ((equal (car a) (car b)) 
    (setf alist (cons (list (car a) (car b)) alist))) 
    (t (join (cdr a) (cdr b) alist blist)))) 

但是函數的輸出總是nil。然後,我在互聯網上查找了一些東西,發現當我嘗試使用setf時,它不再指向原始列表,而是指向一個新的列表。所以如果我不能使用setf,我還能用什麼來實現呢?

+0

我不確定你的功能真的應該做什麼。你想讓你的結果保存兩個輸入列表中相同位置的元素,還是你想要某種交集?如果是後者,那麼重複呢? – danlei

+0

我同意丹尼爾 - 這是一個令人困惑的功能。你能舉一些函數調用和預期輸出的例子嗎?另外,如果函數將兩個列表連接在一起,爲什麼需要四個參數? – zck

+0

您應該始終使用正確縮進的Lisp代碼。 –

回答

1
(defun test (a b) 
    (let ((alist nil) (blist nil)) ; two variables initialized to NIL 
    (progn       ; this PROGN is not needed 
     (join a b alist blist)  ; you call a function, but ignore the 
            ; return value? Why? 
     (print blist))))    ; since blist was never modified, this 
            ; can only be the initial value, NIL 



(defun join (a b alist blist)  ; four new local variables 
    (cond 
    ((and (null a) (null b)) 
    (setf blist (cons alist blist))) ; why do you set the variable BLIST? 
             ; you never use it later 

    ((equal (car a) (car b)) 
    (setf alist (cons (list (car a) (car b)) alist))) 
             ; why do you set the variable ALIST? 
             ; you never use it later 

    (t (join (cdr a) (cdr b) alist blist)))) 
             ; the only recursive call of JOIN 

您只能更改詞彙可達的變量。

1

不要在Lisp中使用「輸出」參數。更好地從函數返回結果。 另外,CL中有一個函數'intersection',它可以做你想做的事情,所以請使用它,除非它是一個練習(然後你可以查看它的實現)。

相關問題