Perché abbiamo sia array frastagliati che array multidimensionali?


89
  1. Qual è la differenza tra array frastagliato e array multidimensionale. C'è un vantaggio l'uno sull'altro?

  2. E perché Visual Studio non mi consente di fare un file

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

    (Lo facevamo in C ++, ma in C # sottolinea [20] con una linea rossa ondulata .. Dice un identificatore di rango non valido)

    ma è contento

    MyClass[,] abc = new MyClass[10,20];
    
  3. Finalmente come posso inizializzarlo in una singola riga (come facciamo in un array semplice con {new xxx...}{new xxx....})

    MyClass[][,][,] itemscollection;
    

11
Il punto centrale di un array frastagliato è che gli array "annidati" non devono essere di dimensioni uniformi.
Ani

1
msdn.microsoft.com/en-us/library/2yd9wwz4(v=vs.71).aspx - La sintassi dell'array multidimensionale come [X, Y] è valida secondo i documenti
ndtreviv

Domanda secondaria aggiuntiva: è possibile utilizzare foreach () con un array multidimensionale?
Serge Wautier

@Serge - ovviamente, come Arrayattrezzi IEnumerable. Puoi sempre provarlo e vedere di persona :)
thecoop

Risposte:


107
  1. Un array frastagliato è un array di array, quindi un int[][]array di int[], ciascuno dei quali può avere lunghezze diverse e occupare il proprio blocco in memoria. Un array multidimensionale ( int[,]) è un singolo blocco di memoria (essenzialmente una matrice).

  2. Non è possibile creare un MyClass[10][20]perché ogni sotto-array deve essere inizializzato separatamente, poiché sono oggetti separati:

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

    A MyClass[10,20]va bene, perché sta inizializzando un singolo oggetto come una matrice con 10 righe e 20 colonne.

  3. A MyClass[][,][,]può essere inizializzato in questo modo (non compilato testato però):

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

Tieni presente che il CLR è fortemente ottimizzato per l'accesso all'array monodimensionale, quindi l'utilizzo di un array frastagliato sarà probabilmente più veloce di un array multidimensionale della stessa dimensione.


6
puoi indicarci qualche prova che gli accessi agli array monodimensionali sono più veloci?
GreyCloud


Esiste un caso d'uso (comune) per l'array multidimensionale?
ryanwebjackson

1
Esempi: scacchiera var board = new Piece[8, 8];, matrice di trasformazione var m = new double[2, 2]; .
Olivier Jacot-Descombes

40

Un array frastagliato è un array di array. Non è garantito che ogni array abbia la stessa dimensione. Potresti avere

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

È un set di array correlati.

Un array multidimensionale, d'altra parte, è più un raggruppamento coeso, come una scatola, un tavolo, un cubo, ecc., Dove non ci sono lunghezze irregolari. Vale a dire

int i = array[1,10];
int j = array[2,10]; // 10 will be available at 2 if available at 1

Ho provato il tuo codice. Non è stato compilato. Prova ad aggiungere int [3] quindi prova jaggedArray[0] = int[3]{ 1, 2, 3 };
barlop

So che questo è vecchio, ma solo a scopo informativo int [3] non è necessario. un semplice int [] è tutto ciò che conta. int [] [] myArray = new int [5] []; myArray [0] = new int [] {1, 2, 3, 4}; Questo è tutto ciò che è necessario.
Velocibadgery

Puoi farlo compilare in C #? Non riesco a compilare jaggedArray[0] = { 1, 2, 3 };se non lo cambio in = new[] { 1, 2, 3 }(o = new int[] { 1, 2, 3 }prima di C # 3.0). Secondo la Guida per programmatori C # di Microsoft , "è possibile dichiarare una variabile di matrice senza crearla, ma è necessario utilizzare il nuovo operatore quando si assegna un nuovo array a questa variabile".
Joel V. Earnest-DeYoung

11

Una matrice rettangolare ha sempre la stessa quantità di colonne per ogni riga.

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

Ogni riga ha 30 colonne, mentre in un array frastagliato, ciò non è necessario. Pertanto, penso che dovrai inizializzare ogni "riga" in un array frastagliato separatamente:

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

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

In effetti, ciò significa che non tutte le righe della matrice frastagliata devono contenere lo stesso numero di elementi. (Nel mio esempio, ha lo stesso numero di elementi, ma non è richiesto).

Puoi farlo perfettamente, ad esempio:

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

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

Questo potrebbe essere un articolo interessante per te.


5

Annuncio 3) Per inizializzare un mostro simile [][,][,], puoi fare qualcosa come:

        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

Se stai cercando un array multidimensionale con limiti fissi, usa sempre la [,]sintassi dello stile. Ciò assicurerà che ogni porzione abbia le stesse dimensioni.

Quando usi [][]ciò che sta realmente accadendo, stai creando un array di array. Ciò significa che ogni array può essere dimensionato in modo diverso. Per esempio:

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

1

La dichiarazione inline sarebbe simile a questa:

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

1

Per # 1, vedi questa domanda SO

Per array inline frastagliati o multidimensionali, vedere questa guida alla programmazione :

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

Non è necessario specificare le dimensioni (array3D), ma se sai che non cambieranno mai, è utile sapere quali dimensioni stai utilizzando (array3Da).


0

Avresti bisogno di capire il funzionamento interno della matrice la matrice multidimensionale agisce come una matrice a dimensione singola tranne che la doppia indicizzazione viene convertita in una singola.

Il tuo array Jagged in c # è un array di oggetti che a sua volta sono array.


0

Penso che l'allocazione di memoria degli array frastagliati 2d in C # sia come gli array 2d in C ++ e C. Poiché gli array frastagliati 2d hanno un puntatore che punta a un array di puntatori che ciascuno di questi puntatori punta a un array di elementi (ad esempio elementi interi); come questo codice in C ++,

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

l'allocazione di memoria del codice seguente è la stessa degli array frastagliati 2d in C #. Ma sono dubbioso, potresti spiegare di più se penso in modo sbagliato.


0

Questo post è vecchio ma qui ci sono i miei pensieri al riguardo.

Gli array irregolari sono array multidimensionali. Gli array multidimensionali sono disponibili in due varietà: rettangolari e frastagliati. Gli array rettangolari rappresentano un blocco n-dimensionale di memoria e gli array frastagliati sono array di array.

Array rettangolari

Le matrici rettangolari vengono dichiarate utilizzando virgole per separare ogni dimensione. La seguente dichiarazione dichiara un array bidimensionale rettangolare, dove le dimensioni sono 3 × 3:

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

Array frastagliati

Le matrici dentellate vengono dichiarate utilizzando parentesi quadre successive per rappresentare ciascuna dimensione. Di seguito è riportato un esempio di dichiarazione di un array bidimensionale frastagliato, dove la dimensione più esterna è 3:

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

0

Per un array multidimensionale pensa a una scatola oa un rettangolo. Ogni riga ha la stessa lunghezza e ogni colonna ha la stessa lunghezza.

In una matrice frastagliata, le righe e le colonne potrebbero non avere le stesse dimensioni. Ad esempio, le colonne o le righe possono avere dimensioni diverse. Ciò porterebbe a una forma che potrebbe non essere una linea retta lungo i lati come un rettangolo. Invece i lati potrebbero essere frastagliati .

Ora ho usato 2 dimensioni / 2 array per questo esempio, ma questo vale per altri.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.