【问题标题】:Why we have both jagged array and multidimensional array?为什么我们既有交错数组又有多维数组?
【发布时间】:2011-06-06 15:24:29
【问题描述】:
  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 arrays visual-studio-2010


【解决方案1】:
  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];
    }
    

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

  3. 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 针对单维数组访问进行了大量优化,因此使用锯齿状数组可能比相同大小的多维数组更快。

【讨论】:

【解决方案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# 中具有灵活性。例如,如果我们必须存储一个人的爱好,首选的方法是使用锯齿状数组,因为不是每个人都有相同数量的爱好。兴趣和许多其他事情也是如此。

                      【讨论】:

                        猜你喜欢
                        • 2020-03-12
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2020-02-01
                        • 2016-02-16
                        • 2015-01-03
                        相关资源
                        最近更新 更多