Почему у нас есть и зубчатый массив, и многомерный массив?

87
  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;
    
Шехар_Про
источник
11
Вся суть зубчатого массива в том, что «вложенные» массивы не обязательно должны быть одинакового размера.
Ani
1
msdn.microsoft.com/en-us/library/2yd9wwz4(v=vs.71).aspx - Синтаксис многомерного массива как [X, Y] действителен в соответствии с документами
ndtreviv
Дополнительный подвопрос: можно ли использовать foreach () с многомерным массивом?
Серж Вотье
@Serge - конечно, как Arrayреализует IEnumerable. Вы всегда можете попробовать и убедиться в этом сами :)
thecoop

Ответы:

102
  1. Неровный массив - это массив массивов, поэтому an 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 MyClass[10,20]в порядке, потому что он инициализирует отдельный объект как матрицу с 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 в значительной степени оптимизирована для доступа к одномерному массиву, поэтому использование зубчатого массива, вероятно, будет быстрее, чем многомерного массива того же размера.

чашка
источник
6
Можете ли вы указать нам на некоторые доказательства того, что доступ к одномерному массиву выполняется быстрее?
GreyCloud
Есть ли (общий) вариант использования многомерного массива?
ryanwebjackson
1
Примеры: клетчатая доска var board = new Piece[8, 8];, матрица трансформации var m = new double[2, 2]; .
Оливье Жако-Декомб
38

Неровный массив - это массив массивов. Не гарантируется, что каждый массив будет иметь одинаковый размер. Ты мог бы иметь

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 };
barlop
Я знаю, что это устарело, но просто для информационных целей int [3] не требуется. просто int [] все, что имеет значение. int [] [] myArray = новый int [5] []; myArray [0] = новый интервал [] {1, 2, 3, 4}; Это все, что нужно.
Velocibadgery
Сможете ли вы скомпилировать это на C #? Я не могу скомпилировать, jaggedArray[0] = { 1, 2, 3 };пока не изменю его на = new[] { 1, 2, 3 }(или = new int[] { 1, 2, 3 }до C # 3.0). Согласно Руководству по программированию на C # от Microsoft: «Вы можете объявить переменную массива, не создавая ее, но вы должны использовать оператор new, когда назначаете новый массив этой переменной».
Джоэл В. Эрнест-ДеЯнг,
11

Прямоугольный массив всегда имеет одинаковое количество столбцов для каждой строки.

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)];
}

Эта статья может быть интересной для вас.

Фредерик Гейзель
источник
5

Объявление 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 };
нан
источник
1

Если вы ищете многомерный массив с установленными границами, всегда используйте [,]синтаксис стиля. Это гарантирует, что каждая порция будет одинакового размера.

Когда вы используете [][]то, что действительно происходит, вы создаете массив массивов. Это означает, что размер каждого массива может быть разным. Например:

int[][] jaggedArray = new int[5][]
for(int index = 0; index < jaggedArray.Length ; ++index)
{
    jaggedArray[index] = new int[index + 1];
}
Джошуа Роджерс
источник
1

Встроенное объявление будет выглядеть примерно так:

int[,] numbers = { {1, 2}, {3, 4}, {5, 6} };
Джозайя Радделл
источник
1

Для # 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).

Rownage
источник
0

Вам необходимо понимать внутреннюю работу массива: многомерный массив действует как одномерный массив, за исключением того, что двойная индексация преобразуется в одиночную.

Ваш массив Jagged в С # - это массив объектов, которые по очереди являются массивами.

двхх
источник
0

Я думаю, что выделение памяти в 2d зазубренных массивах в C # похоже на 2d массивы в C ++ и C. Поскольку 2d зазубренные массивы имеют указатель, который указывает на массив указателей, каждый из этих указателей указывает на массив элементов (например, целые элементы); как этот код на C ++,

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

Распределение памяти в приведенном ниже коде такое же, как для 2-х мерных массивов в C #. Но я сомневаюсь, не могли бы вы объяснить больше, если я ошибаюсь.

ARSD
источник
0

Это старый пост, но вот мои мысли по этому поводу.

Неровные массивы - это многомерные массивы. Многомерные массивы бывают двух видов: прямоугольные и зубчатые. Прямоугольные массивы представляют собой n-мерный блок памяти, а зубчатые массивы - это массивы массивов.

Прямоугольные массивы

Прямоугольные массивы объявляются с использованием запятых для разделения каждого измерения. Следующий оператор объявляет прямоугольный двумерный массив с размерами 3 × 3:

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

Неровные массивы

Неровные массивы объявляются с использованием последовательных квадратных скобок для представления каждого измерения. Вот пример объявления зубчатого двумерного массива, где самое внешнее измерение равно 3:

int[][] matrix = new int[3][];
Имир Ходжа
источник
0

Для многомерного массива представьте себе коробку или прямоугольник. Каждая строка имеет одинаковую длину и каждый столбец одинаковой длины.

В зубчатом массиве строки и столбцы могут быть разных размеров. Например, столбцы или строки могут быть разного размера. Это приведет к форме, которая может не быть прямой линией по бокам, как прямоугольник. Вместо этого стороны могут быть неровными .

Теперь для этого примера я использовал массивы 2 измерения / 2, но это относится и к большему количеству.

Проблема
источник