web-dev-qa-db-ja.com

ジャグ配列と多次元配列の両方があるのはなぜですか?

  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;
    
66
Shekhar_Pro
  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[][,][,]は次のようにinitailizedできます(ただし、コンパイルはテストされていません):

    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は単一次元配列アクセス用に大幅に最適化されているため、ギザギザの配列を使用すると、同じサイズの多次元配列よりも高速になる可能性があります。

80
thecoop

ギザギザの配列は、配列の配列です。各配列が同じサイズであるとは限りません。あなたが持つことができる

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

関連する配列のsetです。

一方、多次元配列は、不規則な長さのないボックス、テーブル、キューブなどのように、まとまりのあるグループです。それは言うことです

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

長方形配列は、常にすべての行に対して同じ量の列を持ちます。

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

これ はあなたにとって興味深い記事かもしれません。

8

広告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 };
4
nan

境界が設定された多次元配列を探している場合は、常に[,]スタイルの構文を使用してください。これにより、各部分のサイズが等しくなります。

[][]を使用するとき、実際に行われているのは、配列の配列を作成しているということです。これは、各アレイのサイズが異なることを意味します。例えば:

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

インライン宣言は次のようになります。

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

#1については、 this SO question

ギザギザまたは多次元のインライン配列については、これを参照してください プログラミングガイド

// Three-dimensional array.
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } };
// Same array with dimensions specified.
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } }, { { 7, 8, 9 }, { 10, 11, 12 } } };

寸法(array3D)を指定する必要はありませんが、寸法が変わらないことがわかっている場合は、使用している寸法(array3Da)を知っておくと役立ちます。

1
rownage

配列の内部動作を理解する必要があります。多次元配列は、二重インデックスが単一の配列に変換されることを除いて、単一の次元配列として機能します。

C#のJagged配列は、配列であるオブジェクトの配列です。

0
dvhh

C#の2Dジャグ配列のメモリ割り当ては、C++およびCの2D配列に似ていると思います。 C++のこのコードのように、

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

以下のコードのメモリ割り当ては、C#の2Dギザギザ配列と同じです。しかし、私は疑っています。間違った方法で考えているなら、もっと説明してください。

0
A.salehy

この投稿は古いですが、ここに私の考えがあります。

ジャグ配列は多次元配列です。多次元配列には、長方形とギザギザの2種類があります。長方形配列はメモリのn次元ブロックを表し、ギザギザ配列は配列の配列です。

長方形の配列

長方形配列は、各次元を区切るためにコンマを使用して宣言されます。次のステートメントは、次元が3×3の長方形の2次元配列を宣言します。

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

ジャグ配列

ギザギザの配列は、各次元を表すために連続する角括弧を使用して宣言されます。ギザギザの2次元配列を宣言する例を次に示します。ここで、最も外側の次元は3です。

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