Чому ми маємо як зубчастий масив, так і багатовимірний масив?


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
Вся суть нерівного масиву полягає в тому, що "вкладені" масиви не повинні мати однаковий розмір.
Ані

1
msdn.microsoft.com/en-us/library/2yd9wwz4(v=vs.71).aspx - Синтаксис багатовимірного масиву як [X, Y] дійсний згідно з документами
ndtreviv

Додаткове підпитання: чи можна використовувати foreach () з багатовимірним масивом?
Serge Wautier

@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] = new int [] {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 , "Ви можете оголосити змінну масиву, не створюючи її, але ви повинні використовувати новий оператор, коли присвоюєте цій масиві новий масив."
Джоель В. Ернест-ДеЮнг

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

Для №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

Вам потрібно було б зрозуміти внутрішню роботу масиву, багатовимірний масив виступає як одновимірний масив, за винятком того, що подвійне індексування перетворюється в єдине.

Ваш нерівний масив в c # - це масив об'єктів, що знаходяться в масивах по черзі.


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

розподіл пам'яті коду нижче такий самий, як 2d зубчасті масиви в C #. Але я сумніваюся, чи не могли б ви пояснити більше, якщо я думаю неправильно?


0

Цей пост старий, але ось мої думки з цього приводу.

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

Прямокутні масиви

Прямокутні масиви оголошуються комами для відокремлення кожного виміру. Наступний оператор оголошує прямокутний двовимірний масив, розміри якого 3 × 3:

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

Нерівні масиви

Нерівні масиви оголошуються за допомогою послідовних квадратних дужок для представлення кожного виміру. Ось приклад оголошення зазубреного двовимірного масиву, де крайній розмір дорівнює 3:

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

0

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

У нерівному масиві рядки та стовпці можуть бути не однакового розміру. Наприклад, стовпці або рядки можуть мати різний розмір. Це призведе до форми, яка може бути не прямою лінією по боках, як прямокутник. Натомість боки можуть бути нерівними .

Зараз я використав 2 розміри / 2 масиви для цього прикладу, але це стосується і більше.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.