0

2 つのリストの共通要素を新しいリストに入れるプログラムを 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、これを実装するために他に何が使用できますか?

4

2 に答える 2

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

字句的に到達可能な変数のみを変更できます。

于 2013-02-06T09:01:25.650 に答える
1

Lisp で「出力」引数を使用しないでください。関数から結果を返すほうがよいでしょう。また、CL には「intersection」という機能がありますので、演習以外で使用してください (その後、その実装を調べることができます)。

于 2013-02-07T08:03:47.830 に答える