【问题标题】:using aref inside a dotimes loop in CL?在 CL 的 dotimes 循环中使用 aref?
【发布时间】:2013-02-02 02:45:21
【问题描述】:

我有一个维度为 '(3 3 2) 的数组,名称为 test-array:

#3A(((0 0) (0 0.1) (0 0.3)) 
    ((1 0) (1 0.1) (1 0.3))
    ((2 0) (2 0.1) (2 0.3)))

请注意,数组中最内部的列表(排名 2)是点坐标,所以通常数组是

#3A(((x0 y0) (x0 y1) (x0 y2)) 
    ((x1 y0) (x1 y1) (x1 y2))
    ((x2 y0) (x2 y1) (x2 y2)))

现在我想使用这个数组中的元素来创建一个新数组。

在该数组的每一行(数组秩:0)上,我想从第一个 xy 坐标中减去第二个 xy 坐标,从第二个中减去第三个 xy 坐标。所以基本上我以参数形式寻找的结果是:

#3A(((x0-x0 y1-y0) (x0-x0 y2-y1)) 
    ((x1-x1 y1-y0) (x1-x1 y2-y1))
    ((x2-x2 y1-y0) (x2-x2 y2-y1))

是否有任何简单的直接函数或操作仅通过操作初始数组来做到这一点?

由于我不知道对此有任何直接操作,我想只是从初始数组中制作一个列表作为新数组的:initial-contents。因此,这种方法的最初目标是获取初始内容列表:

   (((x0-x0 y1-y0) (x0-x0 y2-y1)) 
    ((x1-x1 y1-y0) (x1-x1 y2-y1))
    ((x2-x2 y1-y0) (x2-x2 y2-y1))

为此,我想到了一个使用两次dotimes 的代码(外循环数是行数,内循环数是列数):

(let ((result-1))
  (dotimes (n (array-dimension test-array 0) result-1)
    (setq result-1
      (append result-1
              (let ((result-2))
                (dotimes (m (1- (array-dimension test-array 1)) result-2)
                  (setq result-2
                    (append result-2 
                            (list (- (aref test-array n (1+ m) 0)
                                     (aref test-array n m 0))
                                  (- (aref test-array n (1+ m) 1)
                                     (aref test-array n m 1)))))))))))

但这有一个问题,这也是问题的标题。显然,CL 不喜欢这种为aref 提供输入的“参数”方式(使用 n 和 m):(aref test-array n m 0)

为什么会出现这样的问题?你能想到在循环中使用 aref 的任何其他方法,或者用另一种方法制作 :initial-contents 列表吗?

请注意,这是我实际问题的一种相对简单的形式,因为我拥有的实际初始数组的维度为 (21 16 2) 并且所有 x y 坐标都彼此不同。

非常感谢您的回答......

【问题讨论】:

  • 如果您使用1+(这是一个函数名)而不是+1(这是1 的另一种写法),CL 将不胜感激。
  • @AntonKovalenko 是的,刚刚注意到并更改了它。这是一个打字错误!
  • 此更改使“您的问题中的主要问题”无效,因此您可能需要相应地对其进行编辑。尽管如此,我还是试图回答剩下的问题。

标签: arrays loops lisp common-lisp


【解决方案1】:

正如我在评论中注意到的,返回其参数的函数 加 1 是 1+,而不是 +1(这不是函数名,而是 常量1)。

我认为没有必要在这里构造:initial-contents,因为它没有 比构建目标数组并填充它更容易 在一个循环中作为一个单独的步骤。我就是这样做的:

(defparameter *test-array*
  #3A(((0 0) (0 0.1) (0 0.3)) 
      ((1 0) (1 0.1) (1 0.3))
      ((2 0) (2 0.1) (2 0.3))))

(destructuring-bind (rows cols axes) (array-dimensions *test-array*)
  (let ((result (make-array
                 (list rows (1- cols) axes)
                 :element-type (array-element-type *test-array*))))
    (dotimes (row rows result)
      (dotimes (col (1- cols))
        (dotimes (axis axes)
          (setf (aref result row col axis)
                (- (aref *test-array* row (1+ col) axis)
                   (aref *test-array* row col axis))))))))

我决定让这个例子尽可能简单。选择 解决方案是可能的,例如利用位移到 数组(这就是您使用多维数组的方式 使用序列函数)。我更喜欢简单的方法 这个任务,如果不是更复杂的情况。

【讨论】:

    猜你喜欢
    • 2022-07-28
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多