为啥我们既有交错数组又有多维数组?
Posted
技术标签:
【中文标题】为啥我们既有交错数组又有多维数组?【英文标题】:Why we have both jagged array and multidimensional array?为什么我们既有交错数组又有多维数组? 【发布时间】:2011-06-06 15:24:29 【问题描述】:交错数组和多维数组有什么区别。 彼此之间有好处吗?
为什么 Visual Studio 不允许我做一个
MyClass[][] abc = new MyClass[10][20];
(我们曾经在 C++ 中这样做,但在 C# 中,它用红色蠕动线在 [20] 下划线。表示无效的排名说明符)
但是很满意
MyClass[,] abc = new MyClass[10,20];
最后我怎样才能在一行中初始化它(就像我们在简单的数组中用new xxx...new xxx....
做的那样)
MyClass[][,][,] itemscollection;
【问题讨论】:
锯齿状数组的全部意义在于“嵌套”数组不必具有统一的大小。 msdn.microsoft.com/en-us/library/2yd9wwz4(v=vs.71).aspx - 根据文档,多维数组语法为 [X,Y] 是有效的 附加子问题:是否可以将 foreach() 与多维数组一起使用? @Serge - 当然,因为Array
实现了IEnumerable
。您可以随时尝试并亲自查看:)
What is differences between Multidimensional array and Array of Arrays in C#?的可能重复
【参考方案1】:
锯齿状数组是数组的数组,所以int[][]
是int[]
的数组,每个数组可以有不同的长度并在内存中占用自己的块。多维数组 (int[,]
) 是单个内存块(本质上是一个矩阵)。
您不能创建MyClass[10][20]
,因为每个子数组必须单独初始化,因为它们是单独的对象:
MyClass[][] abc = new MyClass[10][];
for (int i=0; i<abc.Length; i++)
abc[i] = new MyClass[20];
MyClass[10,20]
可以,因为它将单个对象初始化为 10 行 20 列的矩阵。
MyClass[][,][,]
可以这样初始化(虽然没有经过编译测试):
MyClass[][,][,] abc = new MyClass[10][,][,];
for (int i=0; i<abc.Length; i++)
abc[i] = new MyClass[20,30][,];
for (int j=0; j<abc[i].GetLength(0); j++)
for (int k=0; k<abc[i].GetLength(1); k++)
abc[i][j,k] = new MyClass[40,50];
请记住,CLR 针对单维数组访问进行了大量优化,因此使用锯齿状数组可能比相同大小的多维数组更快。
【讨论】:
你能指出一些单维数组访问速度更快的证据吗? @GreyCloud - ***.com/questions/597720/… 多维数组有(常见)用例吗? 例子:棋盘var board = new Piece[8, 8];
,transformation matrixvar m = new double[2, 2];
。【参考方案2】:
锯齿状数组是数组的数组。不保证每个数组的大小相同。你可以有
int[][] jaggedArray = new int[5][];
jaggedArray[0] = new[] 1, 2, 3; // 3 item array
jaggedArray[1] = new int[10]; // 10 item array
// etc.
这是一个相关数组的集合。
另一方面,多维数组更像是一个有凝聚力的分组,如盒子、表格、立方体等,其中没有不规则的长度。也就是说
int i = array[1,10];
int j = array[2,10]; // 10 will be available at 2 if available at 1
【讨论】:
我试过你的代码。它没有编译。尝试添加 int[3] 所以尝试jaggedArray[0] = int[3] 1, 2, 3
;
我知道这是旧的,但只是为了提供信息 int[3] 是不必要的。一个简单的 int[] 才是最重要的。 int[][] myArray = new int[5][]; myArray[0] = new int[] 1, 2, 3, 4;这就是所有必要的。
你能用 C# 编译它吗?我无法编译jaggedArray[0] = 1, 2, 3 ;
,除非我将其更改为= new[] 1, 2, 3
(或C# 3.0 之前的= new int[] 1, 2, 3
)。根据微软的C# Programming Guide,“你可以声明一个数组变量而不创建它,但是你在给这个变量分配一个新数组时必须使用new操作符。”【参考方案3】:
矩形数组的每一行总是有相同数量的列。
MyClass[,] x = new MyClass[10,30]
每行有 30 列,而在锯齿状数组中,这不是必需的。 因此,我认为您必须分别初始化锯齿状数组中的每个“行”:
MyClass[][] x = new MyClass[10][];
for(int i = 0; i < 10; i++)
x[i] = new MyClass[30];
事实上,这意味着交错数组中的每一行都必须包含相同数量的元素。 (在我的示例中,它确实具有相同数量的元素,但这不是必需的)。
你可以完美地做到这一点,例如:
MyClass[][] x = new MyClass[10][];
for(int i = 0; i < 10; i++)
x[i] = new MyClass[(30 + i)];
This 对你来说可能是一篇有趣的文章。
【讨论】:
【参考方案4】:广告 3) 要初始化像 [][,][,]
这样的怪物,你可以这样做:
int [,][,] multiArr1 = new int[,] 2, 2 , 1, 1 ,
new int[,] 2, 2 , 1, 1 ,
new int[,] 2, 2 , 1, 1 ,
new int[,] 2, 2 , 1, 1 ;
int [,][,] multiArr2 = new int[,] 2, 2 , 1, 1 ,
new int[,] 2, 2 , 1, 1 ,
new int[,] 2, 2 , 1, 1 ,
new int[,] 2, 2 , 1, 1 ;
int [][,][,] superMultiArray = multiArr1, multiArr2 ;
【讨论】:
【参考方案5】:如果您正在寻找已设置边界的多维数组,请始终使用[,]
样式语法。这将确保每个部分的大小相同。
当您使用[][]
时,实际情况是您正在创建一个数组数组。这意味着每个数组的大小可以不同。例如:
int[][] jaggedArray = new int[5][]
for(int index = 0; index < jaggedArray.Length ; ++index)
jaggedArray[index] = new int[index + 1];
【讨论】:
【参考方案6】:内联声明看起来像这样:
int[,] numbers = 1, 2, 3, 4, 5, 6 ;
【讨论】:
【参考方案7】:对于#1,请参阅this SO question
对于锯齿状或多维内联数组,请参阅programming guide:
// Three-dimensional array.
int[, ,] array3D = new int[,,] 1, 2, 3 , 4, 5, 6 ,
7, 8, 9 , 10, 11, 12 ;
// Same array with dimensions specified at declaration.
int[, ,] array3Da = new int[2, 2, 3] 1, 2, 3 , 4, 5, 6 ,
7, 8, 9 , 10, 11, 12 ;
您不必指定维度 (array3D),但如果您知道它们永远不会改变,那么了解您使用的维度 (array3Da) 会很有帮助。
【讨论】:
【参考方案8】:对于多维数组,请考虑一个框或矩形。每行长度相同,每列长度相同。
在锯齿状数组中,行和列的大小可能不同。例如,列或行可以是不同的大小。这将导致形状可能不是像矩形那样从侧面向下的直线。相反,边可能是锯齿状的。
现在我在这个例子中使用了 2 个维度/2 个数组,但这适用于更多。
【讨论】:
【参考方案9】:您需要了解数组的内部工作原理 多维数组作为一维数组,除了双索引转换为单索引。
您在 c# 中的 Jagged 数组是一个对象数组,这些对象依次是数组。
【讨论】:
【参考方案10】:我认为 C# 中的二维锯齿状数组内存分配类似于 C++ 和 C 中的二维数组。 因为 2d 锯齿状数组具有指向指针数组的指针,每个指针都指向一个元素数组(例如整数元素);就像这段 C++ 代码,
int** 2DArr new int* [number1];
for (int i = 0; i < number1; i++)
2DArr[i] = new int[number2];
下面代码的内存分配与 C# 中的二维锯齿数组相同。但我对此表示怀疑,如果我的想法有误,请您解释一下。
【讨论】:
【参考方案11】:这篇文章很旧,但这是我对此的看法。
锯齿状数组是多维数组。多维数组有两种:矩形和锯齿状。矩形数组代表一个 n 维的内存块,锯齿状数组是数组的数组。
矩形数组
矩形数组使用逗号分隔每个维度。以下语句声明了一个矩形二维数组,其中维度为 3 × 3:
int[,] matrix = new int [3, 3];
锯齿状数组
锯齿状数组使用连续的方括号来表示每个维度。下面是一个声明锯齿状二维数组的例子,其中最外层维度为 3:
int[][] matrix = new int[3][];
【讨论】:
【参考方案12】: public class ArrayExamples
//Multi-Dimensional Array are of 2 types
//1. Jagged Array: Array of Arrays
//2. rectangular Array: Array having more than one dimension
public void JaggedArray()
//Declaring an array with 3 element. Each element containing single dimension array.
//Benefit: Each single dimension array defined can be of different length.
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[] 1, 2, 3, 4, 5 ;//single dimension array lengh:5
jaggedArray[1] = new int[] 6,7,8;//single dimension array lengh:3
jaggedArray[2] = new int[] 9, 10 ;//single dimension array lengh:2
foreach (var array in jaggedArray)
foreach (var element in array)
Console.WriteLine(element);
public void RectangularArray()
//Declaring a 2 dimensional array with 5 rows and 2 columns.
//Benefits: When we want to declare an array with multiple dimension
//and we know the length as length should be predefined.
//
int[,] array2Dimensional = new int[5,2] 1, 2 , 3, 4 , 5, 6 , 7, 8 , 9, 10 ;
//This loop will go through all the elements
//This will display all the elements i.e. 1,2,3,4,5,6,7,8,9,10
foreach (var element in array2Dimensional)
//Console.WriteLine(element);
//Accessing specific element in the 2 dimensional array.
//i.e. will display 1 which is the first element of first row and first column.
Console.WriteLine(array2Dimensional[0, 0]);
【讨论】:
【参考方案13】:多维数组是 C# 中的矩形数组。它在每个维度中只能有固定数量的元素。下面的代码示例向我们展示了如何在 C# 中声明多维数组。
int[,] multiArray = new[3,3]
交错数组是 C# 中的数组数组。它可以在其中构成不同大小的数组。下面的代码示例向我们展示了如何在 C# 中声明一个锯齿状数组。
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int [1];
jaggedArray[1] = new int[2];
jaggedArray[2] = new int[3];
在上面的代码中,我们创建了大小为 3 的锯齿状数组 jaggedArray,也就是说这个 jaggedArray 是一个由 3 个数组组成的数组。这 3 个数组位于 jaggedArray 的索引 0、1 和 2 处。从示例中可以清楚地看出,所有这些数组的大小都不同。
锯齿状数组应该优于传统的多维数组,因为它们在 C# 中具有灵活性。例如,如果我们必须存储一个人的爱好,首选的方法是使用锯齿状数组,因为不是每个人都有相同数量的爱好。兴趣和许多其他事情也是如此。
【讨论】:
以上是关于为啥我们既有交错数组又有多维数组?的主要内容,如果未能解决你的问题,请参考以下文章