lisp中的动态二维数组

时间:2015-06-02 14:40:52

标签: common-lisp clisp

我想在Lisp中使用2D数组。但每行可以有不同数量的元素(最多5个)。所以我想维护另一个列表来存储每行的当前大小,并在需要时更新它们。

所以,我的代码是这样的:

(setq N (read))
(setq myMatrix (make-array (list N 5)))
(setq sizeArray (make-array N:fill-pointer N))
(dotimes (i N)
    (setf (aref sizeArray i) 0)
)

现在之后我有一个循环来填充每行的元素,如下所示:

(dotimes (i N)
  //Here I need to take input in each row until user presses -1.It is sure he can't insert more than 5 items in each row.
)

如何做到这一点?请帮忙。我试过这样的事情:

(setq item (read-line))
(setf (aref myMatrix i (nthcdr i sizeArray)) item)

但它没有用。

1 个答案:

答案 0 :(得分:1)

Common Lisp中的数组可以有填充指针,这提供了一种将数组视为可以增长和扩展其长度的方法。您的二维数组可以实现为带有填充指针的数组数组。 E.g:

(defun make-row-resizeable-array (rows max-columns)
  "Returns an array of length ROWS containing arrays
of length MAX-COLUMNS, but with a fill pointer initially
set to 0."
  (make-array rows
              :initial-contents (loop for i from 0 below rows
                                   collect (make-array max-columns
                                                       :fill-pointer 0))))

这可以让你这样做:

CL-USER> (let ((array (make-row-resizeable-array 6 5)))
           (vector-push 'x (aref array 2))
           (vector-push 'y (aref array 2))
           (vector-push 'z (aref array 2))
           (vector-push 'a (aref array 3))
           (vector-push 'b (aref array 3))
           array)
;=> #(#() #() #(X Y Z) #(A B) #() #())

你也可以轻松获得长度:

CL-USER> (map 'list 'length *)
;=> (0 0 3 2 0 0)

您可以使用嵌套 aref 调用从数组中获取单个元素:

(let ((array (make-row-resizeable-array 6 5)))
  (vector-push 'x (aref array 2))
  (vector-push 'y (aref array 2))
  (vector-push 'z (aref array 2))
  (vector-push 'a (aref array 3))
  (vector-push 'b (aref array 3))
  (let ((row 3)
        (col 1))
    (aref (aref array row) col)))
;=> B