-1

そのクラスのオブジェクトのリスト要素を逆にするCLOSクラスの関数を書いています。

逆リストを返すメソッドがありますが、オブジェクトのリストをそのリストに設定するにはどうすればよいですか?リストを格納する関数にインスタンス変数を含めて、要素をそれに設定できますか?または、もっと簡単な方法はありますか?

現在の方法は次のとおりです。

(defun my-reverse (lst)
    (cond ((null lst) ‘())
           (t (append (my-reverse (cdr lst)) (car lst)))))

渡されるオブジェクトは(l my-list)であり、アクセサーは(my-list-ls l)になります。

編集:cons2つのリストでは機能しないことに気づきました。

Edit2:正しいコードは次のようになると思います:

(defun my-reverse (l my-list)
        (cond ((null (my-list-ls l) ‘())
               (t (setf (my-list-ls l) (append (my-reverse (cdr (my-list-ls l)))
                                         (car (my-list-ls l)))))))
4

1 に答える 1

1

オブジェクトのスロットを変更する場合は、変更するスロットの値だけでなく、そのオブジェクト自体を関数に渡す必要があります。

編集:質問のedit2について

クラスの名前だと思いますが、実際には関数my-listに渡したくないでしょう?その場合は、をで置き換える必要がありdefunますdefmethod。また、各ステップではなく、リスト全体を逆にした後、インスタンスを1回だけ変更することをお勧めします。そのために内部関数を使用できます。

(defmethod my-reverse ((l my-list))
  (labels ((inner (list acc)
             (if (endp list)
                 acc
                 (inner (rest list) (cons (first list) acc)))))
     (setf (my-list-ls l) (inner (my-list-ls l) ()))))

編集2:詳細な説明

defmethoddefun(ポリモーフィック)メソッドを定義するための代替手段です。ただし、ポリモーフィズムが必要ない場合は(defun my-reverse (l)、最初の行に使用できます。

labels内部関数定義用です。innerここでは、2つのパラメーターlistとで名前が付けられた内部関数を定義しますaccinnerは実際の反転を行う関数であり、反転は末尾再帰とともに自然に行われるため、末尾再帰関数です。(結果は線形の複雑さで構築できるconsため、線形の複雑さですが、ソリューションはそれ自体が一定であるが線形appendであるため、2次の複雑さを必要とします。)consappend

firstrestはとの単なる代替名でcarありcdrendpほとんどの場合、の代替名ですが、引数が実際にはリストでない場合にエラーを通知するnull違いがあります。endp

最後に、最後の行はinner元のリストと空のリストを引数として呼び出し、結果をスロット(別名インスタンス変数)に割り当てます。

于 2011-12-01T07:11:06.540 に答える