【问题标题】:Are the x,y and row, col attributes of a two-dimensional array backwards?二维数组的 x,y 和 row, col 属性是否向后?
【发布时间】:2011-01-13 07:06:25
【问题描述】:

如果我想到 x,y 坐标平面 x,y 是有序对的常用符号,但如果我使用二角钱数组,我有 myArray[row][col] 并且 row 是 y 和 col是 x。这是倒退还是我只是想错了?我在想它看起来像 myArray[x][y] 但如果我想要真正的行和列(比如在游戏板中)那就错了。难道不是 myArray[y][x] 真正模仿行列板吗?

【问题讨论】:

  • 我发现自己向父母提出了同样的问题。很高兴知道没有标准。

标签: multidimensional-array coordinate-systems mathematical-notation


【解决方案1】:

无论好坏,不一致的符号是从数学继承而来的。

多维数组遵循矩阵表示法,其中 Mi,j 表示行 i 和列 j上的矩阵元素>.

因此,如果用于表示矩阵,多维数组向后,但如果用于表示二维笛卡尔平面,则它们看起来会向后,其中 (x, y) 是坐标的典型排序。

另请注意,二维笛卡尔平面通常以 y 轴向上增长的方式定向。然而,这也与二维数组/矩阵的通常可视化方式(以及大多数光栅图像的坐标系)相反。

【讨论】:

    【解决方案2】:

    我喜欢这个问题。你是绝对正确的。大多数时候,我们不是在想 (x, y) 就是 (row, col)。在我质疑它之前已经有好几年了。然后有一天,我意识到我总是将 for 循环视为 x 是一行而 y 是一列,尽管在平面几何中它实际上是相反的。正如许多人所提到的,在大多数情况下这并不重要,但一致性是一件美好的事情。

    【讨论】:

      【解决方案3】:

      如何将数据存储在数组([x][y] 或 [y][x])中并不重要。重要的是您总是以连续的方式遍历数组。 java 二维数组本质上是一个存储第二个数组的一维数组(例如,在 [y][x] 的情况下,您有一个长数组 [y],其中每个 y 都保存相应的 [x] 数组y 行)。

      为了有效地遍历整个数组,以某种方式访问​​数据很重要,这样您就不必连续在该数组中进行搜索,从一个 y-array-of-xarrays 跳转到另一个 y-array -of-xarrays。您要做的是访问一个 y 元素并访问其中的所有 x,然后再移动到下一个 y 元素。

      所以在 Array[y][x] 情况下。第一个变量总是在外循环,第二个在内循环:

      for (int ys = 0; ys < Array.length; ys++)
          for (int xs = 0; xs < Array[y].length; xs++)
          {
              do  your stuff here
          }
      

      当然,还要在循环之外预先分配两个 Array.length,以防止每次循环都必须获取这些值。

      【讨论】:

        【解决方案4】:

        这是我为自己的理智所做的:

        int x = array[0].length;
        int y = array.length;
        

        然后对于我进行的每一个数组调用,我都会写:

        array[y][x]
        

        这对于图形算法和水平/垂直矩阵翻转特别有用。

        【讨论】:

        • 这个问题很受欢迎。有趣的是,这些年来情况如何。我必须记住这个答案。谢谢。
        【解决方案5】:

        不是真的,如果你认为一行是 x 轴上的元素,然后一个二维数组是 y 轴上的一堆行元素,那么使用 y 对一行进行操作是正常的,因为你已经知道 x (对于特定的行 x 总是相同的,它是 y 随其索引而变化),然后使用 x 对多个行元素进行操作(行垂直堆叠,每一行都具有特定的 y 值)

        【讨论】:

          【解决方案6】:

          你说得对,但确实感觉有点倒退。行号是y坐标,列号是x坐标,但是我们通常写row,col但也通常写x,y。

          您是想将数组写成 [y][x] 还是 [x][y] 主要取决于您对内存布局的实际关心程度(如果这样做,您使用什么语言)。以及是否要编写可以单独对行或列进行操作的函数/方法。

          如果您正在编写 C/C++ 代码,则数组存储在 Row Major Order 中,这意味着可以将单行数据视为一维数组。但是单列数据不能。如果我没记错的话,VB 使用列主顺序,所以语言会有所不同。我会惊讶于 C# 也不是主要顺序,但我不知道。

          【讨论】:

          • 这是我在 20 分钟的搜索中读到的最清晰的解释
          • C# 是主要列。检查:声明一个多维数组,如int a[2, 2];在不安全的块中,修复第一个元素:fixed(int* p = &a[0,0]),然后迭代 int* q = p;每个步骤的 q++。如果数组被初始化 int[,] a = new int[2, 2] { { 1, 2 }, { 3, 4 } };您会看到 1、2、3、4。如果它是主要行,您将首先看到要更改的行维度(第一个维度)。
          • @ILoveFortran 您的示例向我表明 C# 是行优先的({1, 2} 是一行)。鉴于 C# 来自其他类 C 语言的血统,行专业似乎更有可能。另请参阅stackoverflow.com/q/68049499 的 cmets,它解释了 CLI 被指定为使用行优先顺序。
          • @jamesdlin,你是对的,我翻转了 row-major 和 column-major 的定义。这个术语有问题。我在考虑列优先(列索引变化最快),这是行优先的。
          【解决方案7】:

          我敢打赌,对此有很多不同的看法。底线是,只要您始终如一,这并不重要。如果您有其他库或类似库将使用相同的数据,那么为了更轻松地集成,您可以做任何事情。

          如果这完全是在您自己的代码中,请执行您认为合适的任何操作。我个人的偏好是使用 myArray[y][x]。如果它们很大,将要同时访问的项目放在一起可能会带来性能优势。但如果有的话,我不会担心这个,直到很晚的时候。

          【讨论】:

            【解决方案8】:

            其实,这取决于你。你的问题没有思考的权利。例如,我通常将一维数组视为一行单元格。所以,在我看来,它是数组 [col] [row]。但这真的取决于你......

            【讨论】:

            • 如果您正在考虑缓存后果,那么一种正确的看待它的方式...
            • @mmeyers:不是真的,效果是你把游戏板放在一边。以这种方式存储图像很常见。
            • 我认为这个问题没有任何给定的上下文......当然在不同的上下文中,有不同的逻辑。
            • @Joel: 1) 只要你仍然正确地迭代,不管你是怎么想的,是的。这可能需要(从您的角度)逐列而不是逐行进行。 2) 当你叫我 mmeyers 时,我没有收到通知。这是自实施通知以来发生的第四次。 :)
            猜你喜欢
            • 1970-01-01
            • 2011-05-28
            • 2012-01-01
            • 2019-06-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-11-14
            • 1970-01-01
            相关资源
            最近更新 更多