【问题标题】:Multidimensional arrays in Java and C#Java 和 C# 中的多维数组
【发布时间】:2011-07-15 21:22:31
【问题描述】:

在 C# 中,有两种方法可以创建多维数组。

int[,] array1 = new int[32,32];

int[][] array2 = new int[32][];
for(int i=0;i<32;i++) array2[i] = new int[32];

我知道第一种方法在内部创建一个一维数组,而第二种方法创建一个数组数组(访问速度较慢)。

但是在 Java 中,没有 [,] 这样的东西,我看到多维数组是这样声明的:

int[][] array3 = new int[32][32];

由于这种语法在 C# 中是非法的,而 Java 没有 int[,],我想知道这是否等同于 array1?还是还是数组数组?

【问题讨论】:

标签: c# java arrays multidimensional-array jagged-arrays


【解决方案1】:

它仍然是一个数组数组。只是在 C# 中,您必须在循环中创建每个子数组。所以这个Java:

// Java
int[][] array3 = new int[32][32];

相当于这个C#:

// C#
int[][] array3 = new int[32][];
for (int i = 0; i < array3.Length; i++)
{
    array3[i] = new int[32];
}

(正如 Slaks 所说,在 .NET 中,锯齿状数组通常比矩形数组更快。但它们在内存方面的效率较低。)

【讨论】:

    【解决方案2】:

    你错了;锯齿状(嵌套)数组更快。 (CLR 已针对它们进行了优化)

    Java 不支持真正的多维数组;这是一个参差不齐的数组。
    Java 语法自动创建所有内部数组;在 C# 中,这需要一个单独的循环。

    【讨论】:

    • 嵌套数组基本上比真正的多维数组慢。每个嵌套级别都有一个间接级别(一个额外的指针跟随),并且在大多数情况下不是最佳的内存位置。
    • @rlibby:你说得对,它们比一维数组慢。但是,.Net 2d 数组的效率较低。 (请注意,我没有测量过)
    • 我刚刚做了一个快速基准测试,在 C# 中,迭代一个二维数组(例如int[x, y])所需的时间大约是迭代一个相同大小的一维数组的两倍。幸好 18 个月的摩尔定律解决了这个问题。 :) 我没有将二维数组与锯齿状数组进行比较。
    • @rlibby:CLR 中有两种类型的数组:vectors(始终从零开始和一维)和 arrays(它们可能是多维的并且可能没有零基数)。我怀疑是额外的“它可能没有零基”算术在这里有所作为。不过只是猜测。
    • @Hannesh:它们在 .Net 的实现中速度较慢。它们本质上并不慢。它们速度较慢/不支持的原因是它们的使用不多。
    【解决方案3】:

    由于人们担心 .NET 中多维数组与交错数组的性能,我实施了一些测试,并在 8k x 8k 元素上对结果进行了基准测试:

    测试是:

    1. 多维二维数组
    2. 多维索引向后(y 优先)
    3. 使用 GetLength(x) 而不是整数边界的多维
    4. 与向后的索引交错
    5. 交错
    6. 一维(大小 x 大小)与索引中的乘法
    7. 带增量索引的一维

    结果:

    one <> Elapsed Time: 0.543558s
    two <> Elapsed Time: 0.8911516s
    three <> Elapsed Time: 0.8908123s
    four <> Elapsed Time: 1.1367238s
    five <> Elapsed Time: 0.3039648s
    six <> Elapsed Time: 0.8110969s
    seven <> Elapsed Time: 0.2629394s
    

    为了好玩,我也在 WP7 模拟器上运行了它们,得到了相似的数字。

    测试函数代码为here

    【讨论】:

    • 您的第六次测试不正确(根据您的测试描述),因为您使用 x + ysize 作为偏移量,从而在数组中跳跃。偏移量当然应该是 xsize + y。
    【解决方案4】:

    在 Java 中,您要声明一个数组数组。

    您可以通过以下代码看到这一点:

    int[][] arrOfArr = new int[5][];
    arrOfArr[0] = new int[5];
    arrOfArr[1] = new int[1];
    arrOfArr[2] = new int[9];
    ...
    

    int[][] arr = new int[3][3]; 只是以下的简写:

    int[][] arr = new int[3][];
    arr[0] = new int[3];
    arr[1] = new int[3];
    arr[2] = new int[3];
    

    【讨论】:

      【解决方案5】:

      我正在将一些 Java 代码翻译成 C# - 这就是我如何处理 Jagged 数组

          //Java
          private static int grad3[][] = {{1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},{1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},{0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}};
      
          //C#
          private static int[,] grad3setup = { { 1, 1, 0 }, { -1, 1, 0 }, { 1, -1, 0 }, { -1, -1, 0 }, { 1, 0, 1 }, { -1, 0, 1 }, { 1, 0, -1 }, { -1, 0, -1 }, 
                                        { 0, 1, 1 }, { 0, -1, 1 }, { 0, 1, -1 }, { 0, -1, -1 } };
      
          private static int[][] grad3
          {
              get
              {
                  int[][] grad3 = new int[12][];
                  for (int i = 0; i < grad3.Length; i++)
                  {
                      grad3[i] = new int[3] { grad3setup[i, 0], grad3setup[i, 1], grad3setup[i, 2] };
                  }
                  return grad3;
              }
          }
      

      【讨论】:

        【解决方案6】:

        它是一个数组数组,具有与 C# 中相同的性能折衷。 如果您知道您的数组数组不会是锯齿状的,那么您可以将它包装在一个类中,以便在一维支持数组上获得二维索引。

        【讨论】:

          猜你喜欢
          • 2015-12-12
          • 2012-02-06
          • 1970-01-01
          • 1970-01-01
          • 2016-06-22
          • 2021-12-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多