Java 和 C# 中的多维数组
Posted
技术标签:
【中文标题】Java 和 C# 中的多维数组【英文标题】:Multidimensional arrays in Java and 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
?还是还是数组数组?
【问题讨论】:
另见***.com/questions/168897/… 不,在 c# 中有一种方法可以创建多维数组。另一个创建一个 jagged 数组。它们是两种不同的东西。 【参考方案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 元素上对结果进行了基准测试:
测试是:
-
多维二维数组
多维索引向后(y 优先)
使用 GetLength(x) 而不是整数边界的多维
与向后的索引交错
交错
一维(大小 x 大小)与索引中的乘法
带增量索引的一维
结果:
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# 中相同的性能折衷。 如果您知道您的数组数组不会是锯齿状的,那么您可以将它包装在一个类中,以便在一维支持数组上获得二维索引。
【讨论】:
以上是关于Java 和 C# 中的多维数组的主要内容,如果未能解决你的问题,请参考以下文章