3

我构建了一个由向量​​组成的二维数组(矩阵):

(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]]

有用。

接下来,我尝试构建一个函数,该函数采用这种方法在这样的二维数组中设置第 (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]]

看起来数组的所有行都链接到同一个向量,因此更改该向量会更改所有行。

所以有两个问题:(1)为什么在第二种情况下会发生这种情况,而不是第一种情况?(2) 我该如何解决这个问题(这样我就可以访问以这种方式表示的二维数组的第 (i, j) 个条目)?

(我最初是编写一个小例程来添加两个矩阵,表示为上述向量的向量,并且遇到了同样的问题。我认为上面的精简示例可能会使问题更清楚。)

4

1 回答 1

3

在第一种情况下,您正在用另一个向量替换“外部”向量中的一个元素(而其他三个“内部”向量仍然都指向同一个元素)。在第二种情况下,您替换“内部”向量中的一个元素(并且根据您的示例,您只有一个内部向量重复了四次。将向量初始化为不同的不同向量的一种简单方法是这样的:

(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 回答