2013-02-06 2 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

Не используйте аргументы «output» в Lisp. Лучше вернуть результат из функции. Кроме того, в CL есть функция 'пересечения', которая делает то, что вы хотите, поэтому, пожалуйста, используйте ее, если это не упражнение (тогда вы можете найти ее реализацию).