为什么我们既有锯齿状数组又有多维数组?

Why we have both jagged array and multidimensional array?

提问人:Shekhar_Pro 提问时间:1/11/2011 最后编辑:CœurShekhar_Pro 更新时间:2/24/2022 访问量:69636

问:

  1. 交错数组和多维数组有什么区别。 一个对另一个有好处吗?

  2. 为什么 Visual Studio 不允许我做

    MyClass[][] abc = new MyClass[10][20];
    

    (我们曾经在 C++ 中这样做,但在 C# 中,它用红色的蠕动线在 [20] 下划线。说无效的排名说明符)

    但很满意

    MyClass[,] abc = new MyClass[10,20];
    
  3. 最后,我怎样才能在一行中初始化它(就像我们在简单数组中所做的那样{new xxx...}{new xxx....})

    MyClass[][,][,] itemscollection;
    
C# .NET 数组 visual-studio-2010

评论

16赞 Ani 1/11/2011
锯齿状数组的全部意义在于,“嵌套”数组不必具有统一的大小。
1赞 ndtreviv 1/11/2011
msdn.microsoft.com/en-us/library/2yd9wwz4(v=vs.71).aspx - 根据文档,[X,Y] 的多维数组语法是有效的
0赞 Serge Wautier 1/11/2011
附加子问题:是否可以将 foreach() 与多维数组一起使用?
0赞 thecoop 1/11/2011
@Serge - 当然,作为工具.您可以随时尝试一下,亲眼看看:)ArrayIEnumerable
0赞 nawfal 4/25/2013
C# 中多维数组和数组数组之间有什么区别的可能重复?

答:

49赞 Anthony Pegram 1/11/2011 #1

交错数组是数组的数组。不保证每个数组的大小相同。你可以有

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

评论

0赞 barlop 2/22/2016
我试过你的代码。它没有编译。尝试添加 int[3] 所以尝试jaggedArray[0] = int[3]{ 1, 2, 3 };
0赞 Velocibadgery 2/17/2018
我知道这是旧的,但仅供参考,int[3]是没有必要的。一个简单的 int[] 才是最重要的。int[][] myArray = 新 int[5][];myArray[0] = 新 int[] {1, 2, 3, 4};这就是所有必要的。
0赞 Joel V. Earnest-DeYoung 7/29/2020
你能把它用 C# 编译吗?除非我将其更改为(或 C# 3.0 之前),否则我无法编译。根据 Microsoft 的 C# 编程指南,“您可以在不创建数组变量的情况下声明它,但在将新数组分配给此变量时必须使用 new 运算符。jaggedArray[0] = { 1, 2, 3 };= new[] { 1, 2, 3 }= new int[] { 1, 2, 3 }
140赞 thecoop 1/11/2011 #2
  1. 锯齿状数组是数组的数组,因此 是 的数组,每个数组可以具有不同的长度并在内存中占据自己的块。多维数组 () 是单个内存块(本质上是一个矩阵)。int[][]int[]int[,]

  2. 您不能创建一个,因为每个子数组都必须单独初始化,因为它们是单独的对象:MyClass[10][20]

    MyClass[][] abc = new MyClass[10][];
    
    for (int i=0; i<abc.Length; i++) {
        abc[i] = new MyClass[20];
    }
    

    A 是可以的,因为它将单个对象初始化为具有 10 行和 20 列的矩阵。MyClass[10,20]

  3. A 可以像这样初始化(虽然没有经过编译测试):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 针对单维数组访问进行了大量优化,因此使用交错数组可能比相同大小的多维数组更快。

评论

11赞 GreyCloud 1/11/2011
您能给我们指出一些证据表明一维数组访问速度更快吗?
9赞 thecoop 1/11/2011
@GreyCloud - stackoverflow.com/questions/597720/...
0赞 ryanwebjackson 10/31/2017
多维数组是否有(常见)用例?
2赞 Olivier Jacot-Descombes 4/28/2019
例如:方格板、变换矩阵var board = new Piece[8, 8];var m = new double[2, 2];
13赞 Frederik Gheysels 1/11/2011 #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)];
}

这对您来说可能是一篇有趣的文章。

1赞 Joshua Rodgers 1/11/2011 #4

如果要查找具有设置边界的多维数组,请始终使用样式语法。这将确保每个部分的大小相等。[,]

当你使用时,真正发生的事情是你正在创建一个数组的数组。这意味着每个数组的大小可以不同。例如:[][]

int[][] jaggedArray = new int[5][]
for(int index = 0; index < jaggedArray.Length ; ++index)
{
    jaggedArray[index] = new int[index + 1];
}
1赞 Josiah Ruddell 1/11/2011 #5

内联声明如下所示:

int[,] numbers = { {1, 2}, {3, 4}, {5, 6} };
1赞 rownage 1/11/2011 #6

对于 #1,请参阅此 SO 问题

对于交错或多维内联数组,请参阅以下编程指南

// 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) 会很有帮助。

0赞 dvhh 1/11/2011 #7

您需要了解阵列的内部工作 多维数组充当单维数组,只是将双索引转换为单索引。

c# 中的 Jagged 数组是一个对象数组,这些对象轮流为数组。

6赞 nan 1/11/2011 #8

广告 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 };
0赞 A.R.S.D. 2/1/2018 #9

我认为 C# 中的 2d 锯齿状数组内存分配就像 C++ 和 C 中的 2d 数组。 因为二维锯齿状数组具有指向指针数组的指针,因此每个指针都指向一个元素数组(例如整数元素);就像 C++ 中的这段代码一样,

int** 2DArr {new int* [number1]};
for (int i = 0; i < number1; i++)
{
   2DArr[i] = new int[number2];
}

下面代码的内存分配与 C# 中的二维锯齿状数组相同。但我对此表示怀疑,如果我的想法是错误的,你能解释更多吗?

0赞 Imir Hoxha 8/30/2019 #10

这篇文章很旧,但这是我对此的看法。

交错数组是多维数组。多维数组有两种类型:矩形和锯齿状。矩形数组表示 n 维内存块,交错数组是数组的数组。

矩形数组

矩形数组使用逗号声明以分隔每个维度。以下语句声明一个矩形二维数组,其维度为 3 × 3:

int[,] matrix = new int [3, 3]; 

锯齿状阵列

交错数组使用连续的方括号来表示每个维度。下面是声明锯齿状二维数组的示例,其中最外层的维度为 3:

int[][] matrix = new int[3][];
1赞 Roblem 12/2/2019 #11

对于多维数组,请考虑一个盒子或矩形。每行的长度相同,每列的长度也相同。

在交错数组中,行和列的大小可能不同。例如,列或行的大小可能不同。这将导致形状可能不是像矩形那样沿两侧的直线。相反,两侧可能是锯齿状的。

现在我在这个例子中使用了 2 维/2 数组,但这适用于更多。

0赞 maxspan 12/8/2021 #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]);
            }
        }
2赞 Muhammad Junaid 2/24/2022 #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# 中具有灵活性。例如,如果我们必须存储一个人的爱好,首选方法是使用锯齿状数组,因为不是每个人都有相同数量的爱好。同样的事情也适用于兴趣和许多其他事情。