【问题标题】:Dynamic 2d array in lisplisp中的动态二维数组
【发布时间】:2015-06-02 14:40:51
【问题描述】:

我想在 Lisp 中有一个二维数组。但是每一行可以有不同数量的元素(最多 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或@987654325 @),或使用向量的向量。
  • Nthcdr 适用于列表,而不适用于数组。我想你想要(aref size-array i) 那里。
  • N:fill-pointer 是包n 中的符号fill-pointer。我认为你在那里缺少一个空间。
  • 请注意,默认的 readtable 会大写它读取的所有内容,因此驼峰式大小写没有任何意义。
  • 另外,// 不引入评论。行 cmets 以一个或多个 ; 开头。

标签: common-lisp clisp


【解决方案1】:

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

(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

【讨论】:

  • 以及如何获得第 i 行第 j 列值说我想要第 3 行第一列值,例如:X
  • 主要问题不是填充数组而是访问元素
  • 这就像访问一个数组,你只需说(aref (aref ...) ...)。我刚刚更新了。
  • “主要问题不是填充数组而是访问元素”虽然我看到您在问题的最后一句中询问了这个问题,但标题和第一句“动态二维数组在lisp; 我想在 Lisp 中有一个 2D 数组”听起来你想要一种方法来拥有一个具有动态大小行的 2d 数组。至于设置它们,我用 vector-push 说明了这一点。请注意,如果您执行(dotime (i rows) (loop-for-user-input (vector-push (user-input) (aref array i))),您将构建您想要的结构。
  • 那么只访问第 i 行的长度呢?而不是整个矩阵
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 2018-09-03
  • 1970-01-01
  • 2011-07-03
  • 2017-07-06
  • 2014-06-03
  • 2018-08-07
相关资源
最近更新 更多