Mengapa kita memiliki array bergerigi dan array multidimensi?

89
  1. Apa perbedaan antara Jagged Array dan Multidimensional Array. Apakah ada manfaat satu sama lain?

  2. Dan mengapa Visual Studio tidak mengizinkan saya melakukan file

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

    (Kami biasa melakukannya di C ++, tetapi di C # itu menggarisbawahi [20] dengan garis bergelombang merah .. Mengatakan penentu peringkat tidak valid)

    tapi senang dengan

    MyClass[,] abc = new MyClass[10,20];
    
  3. Akhirnya bagaimana saya bisa menginisialisasi ini dalam satu baris (seperti yang kita lakukan dalam array sederhana dengan {new xxx...}{new xxx....})

    MyClass[][,][,] itemscollection;
    
Shekhar_Pro
sumber
11
Inti dari array bergerigi adalah bahwa array "bersarang" tidak perlu memiliki ukuran yang seragam.
Ani
1
msdn.microsoft.com/en-us/library/2yd9wwz4(v=vs.71).aspx - Sintaks array multidimensi karena [X, Y] valid menurut dokumen
ndtreviv
Sub-pertanyaan tambahan: Apakah mungkin menggunakan foreach () dengan larik multi-dimensi?
Serge Wautier
@Serge - tentu saja, sebagai Arrayimplementasi IEnumerable. Anda selalu dapat mencobanya dan melihatnya sendiri :)
kandang

Jawaban:

107
  1. Larik bergerigi adalah larik-larik, jadi an int[][]adalah larik int[], yang masing-masing dapat memiliki panjang yang berbeda dan menempati bloknya sendiri dalam memori. Array multidimensi ( int[,]) adalah satu blok memori (pada dasarnya matriks).

  2. Anda tidak dapat membuat MyClass[10][20]karena setiap sub-larik harus diinisialisasi secara terpisah, karena mereka adalah objek terpisah:

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

    A MyClass[10,20]ok, karena ini menginisialisasi satu objek sebagai matriks dengan 10 baris dan 20 kolom.

  3. A MyClass[][,][,]dapat diinisialisasi seperti itu (meskipun tidak dikompilasi diuji):

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

Ingat, CLR sangat dioptimalkan untuk akses array dimensi tunggal, jadi menggunakan array bergerigi kemungkinan akan lebih cepat daripada array multidimensi dengan ukuran yang sama.

kandang
sumber
6
dapatkah Anda menunjukkan beberapa bukti bahwa akses array dimensi tunggal lebih cepat?
GreyCloud
Apakah ada kasus penggunaan (umum) untuk larik multi-dimensi?
ryanwebjackson
1
Contoh: papan kotak-kotak var board = new Piece[8, 8];, matriks transformasi var m = new double[2, 2]; .
Olivier Jacot-Descombes
40

Larik bergerigi adalah larik larik. Setiap larik tidak dijamin memiliki ukuran yang sama. Kamu bisa saja

int[][] jaggedArray = new int[5][];
jaggedArray[0] = new[] {1, 2, 3}; // 3 item array
jaggedArray[1] = new int[10];     // 10 item array
// etc.

Ini adalah satu set array terkait.

Larik multidimensi, di sisi lain, lebih merupakan pengelompokan yang kohesif, seperti kotak, tabel, kubus, dll., Di mana tidak ada panjang yang tidak beraturan. Artinya

int i = array[1,10];
int j = array[2,10]; // 10 will be available at 2 if available at 1
Anthony Pegram
sumber
Saya mencoba kode Anda. Itu tidak dapat dikompilasi. Coba tambahkan int [3] jadi Coba jaggedArray[0] = int[3]{ 1, 2, 3 };
barlop
Saya tahu ini sudah tua, tetapi hanya untuk tujuan informasional [3] tidak perlu. int [] sederhana adalah yang terpenting. int [] [] myArray = new int [5] []; myArray [0] = int baru [] {1, 2, 3, 4}; Ini semua yang diperlukan.
Velocibadgery
Bisakah Anda mendapatkan ini untuk dikompilasi di C #? Saya tidak dapat mengkompilasi jaggedArray[0] = { 1, 2, 3 };kecuali saya mengubahnya ke = new[] { 1, 2, 3 }(atau = new int[] { 1, 2, 3 }sebelum C # 3.0). Menurut Panduan Pemrograman C # Microsoft , "Anda dapat mendeklarasikan variabel array tanpa membuatnya, tetapi Anda harus menggunakan operator baru saat menetapkan array baru ke variabel ini."
Joel V. Earnest-DeYoung
11

Larik persegi panjang selalu memiliki jumlah kolom yang sama untuk setiap baris.

MyClass[,] x = new MyClass[10,30]

Setiap baris memiliki 30 kolom, sedangkan dalam array bergerigi, ini tidak diperlukan. Oleh karena itu, saya pikir Anda harus menginisialisasi setiap 'baris' dalam array bergerigi secara terpisah:

MyClass[][] x = new MyClass[10][];

for(int i = 0; i < 10; i++)
{
    x[i] = new MyClass[30];
}

Faktanya, ini berarti bahwa tidak setiap baris dalam jagged array harus mengandung jumlah elemen yang sama. (Dalam contoh saya, itu memang memiliki jumlah elemen yang sama, tetapi ini tidak wajib).

Anda dapat melakukan ini dengan sempurna, misalnya:

MyClass[][] x = new MyClass[10][];

for(int i = 0; i < 10; i++)
{
    x[i] = new MyClass[(30 + i)];
}

Ini mungkin artikel yang menarik untuk Anda.

Frederik Gheysels
sumber
5

Ad 3) Untuk menginisialisasi monster seperti itu [][,][,], Anda dapat melakukan sesuatu seperti:

        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 };
nan
sumber
1

Jika Anda mencari larik multi-dimensi yang memiliki batas yang ditetapkan, selalu gunakan [,]sintaks gaya. Ini akan memastikan bahwa setiap porsi berukuran sama.

Saat Anda menggunakan [][]apa yang sebenarnya terjadi adalah Anda membuat array dari array. Ini berarti bahwa setiap larik dapat berukuran berbeda. Sebagai contoh:

int[][] jaggedArray = new int[5][]
for(int index = 0; index < jaggedArray.Length ; ++index)
{
    jaggedArray[index] = new int[index + 1];
}
Joshua Rodgers
sumber
1

Deklarasi sebaris akan terlihat seperti ini:

int[,] numbers = { {1, 2}, {3, 4}, {5, 6} };
Josiah Ruddell
sumber
1

Untuk # 1, lihat pertanyaan SO ini

Untuk larik sejajar bergerigi atau multidimensi, lihat panduan pemrograman ini :

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

Anda tidak perlu menentukan dimensi (array3D), tetapi jika Anda tahu bahwa mereka tidak akan pernah berubah, akan sangat membantu untuk mengetahui dimensi apa yang Anda gunakan (array3Da).

kerusakan
sumber
0

Anda perlu memahami cara kerja internal array, array multi-dimensi bertindak sebagai array dimensi tunggal kecuali bahwa pengindeksan ganda diubah menjadi satu.

Array Bergerigi Anda di c # adalah larik objek yang merupakan larik bergantian.

dvhh
sumber
0

Saya berpikir bahwa alokasi memori array bergerigi 2d di C # adalah seperti array 2d di C ++ dan C. Karena array bergerigi 2d memiliki pointer yang menunjuk ke array pointer yang masing-masing pointer ini menunjuk ke array elemen (misalnya elemen integer); seperti kode ini di C ++,

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

alokasi memori kode di bawah ini sama dengan array bergerigi 2d di C #. Tetapi saya ragu, dapatkah Anda menjelaskan lebih lanjut jika saya berpikir secara salah.

ARSD
sumber
0

Posting ini sudah tua tapi inilah pemikiran saya tentang itu.

Array bergerigi adalah array multidimensi. Array multidimensi tersedia dalam dua jenis: persegi panjang dan bergerigi. Larik persegi panjang mewakili blok memori berdimensi-n, dan larik bergerigi adalah larik larik.

Array persegi panjang

Array persegi panjang dideklarasikan menggunakan koma untuk memisahkan setiap dimensi. Pernyataan berikut mendeklarasikan array dua dimensi persegi panjang, di mana dimensinya 3 × 3:

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

Array bergerigi

Array bergerigi dideklarasikan menggunakan tanda kurung siku yang berurutan untuk mewakili setiap dimensi. Berikut adalah contoh mendeklarasikan larik dua dimensi bergerigi, dengan dimensi terluar adalah 3:

int[][] matrix = new int[3][];
Imir Hoxha
sumber
0

Untuk array multi-dimensi, pikirkan kotak atau persegi panjang. Setiap baris memiliki panjang yang sama dan setiap kolom memiliki panjang yang sama.

Dalam larik bergerigi, baris dan kolom mungkin tidak memiliki ukuran yang sama. Misalnya, kolom atau baris mungkin memiliki ukuran yang berbeda. Ini akan menghasilkan bentuk yang mungkin bukan garis lurus ke bawah seperti persegi panjang. Sebaliknya, sisi-sisinya mungkin bergerigi .

Sekarang saya menggunakan array 2 dimensi / 2 untuk contoh ini, tetapi ini berlaku untuk lebih.

Roblem
sumber