3

ベクトルのベクトルで構成される2次元配列(行列)を作成します。

(setq zero-row [0 0 0 0 0])
  => [0 0 0 0 0]

(setq zero-mat (make-vector 4 zero-row))
  => [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

行2を変更された要素を含むベクトルに置き換えることにより、行2、列3(0インデックス)の要素を42に設定します。

(aset zero-mat 2 [0 0 0 42 0])
  => [0 0 0 42 0]

zero-mat
  => [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 42 0] [0 0 0 0 0]]

できます。

次に、このアプローチを使用して、このような2次元配列の(i、j)番目の要素を設定する関数を作成します。

(defun matrix-set (mat i j elt)
"Set the (i, j)-th element of mat to elt. mat is a vector of the row vectors. Indexing is 0-based in each component."
(let ((vect (aref mat i)))
   (aset vect j elt)
   (aset mat i vect)
   mat))

しかし、これは機能しません:

(setq zero-row [0 0 0 0 0])
  => [0 0 0 0 0]

(setq zero-mat (make-vector 4 zero-row))
  => [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

(matrix-set zero-mat 2 3 42)
  => [[0 0 0 42 0] [0 0 0 42 0] [0 0 0 42 0] [0 0 0 42 0]]

配列のすべての行が同じベクトルにリンクされているように見えるため、そのベクトルを変更するとすべての行が変更されます。

したがって、2つの質問があります。(1)これが2番目のケースで発生するのに、最初のケースでは発生しないのはなぜですか。(2)これを修正するにはどうすればよいですか(このように表された2次元配列の(i、j)番目のエントリにアクセスできるように)?

(私はもともと、上記のようにベクトルのベクトルとして表される2つの行列を追加するための小さなルーチンを作成していましたが、同じ問題が発生しました。上記の簡略化された例により、問題がより明確になると思います。)

4

1 に答える 1

3

最初のケースでは、「外部」ベクトルの要素を別のベクトルに置き換えています (他の 3 つの「内部」ベクトルはすべて同じ要素を指しています)。2番目のケースでは、「内部」ベクトルの要素を置き換えます(例のように、4回複製された内部ベクトルは1つだけです。ベクトルを異なる個別のベクトルに初期化する簡単な方法は次のようになります:

(let ((i 0) (new-vector (make-vector 4 nil))
 (while (< (progn (aset new-vector i (make-vector 5 0))
                  (incf i))
           (length new-vector)))

適当に書いたので誤字脱字ありましたらすみません。しかし、アイデアはそれを理解するのに十分単純でなければなりません。

于 2013-01-30T07:09:58.717 に答える