5

n 個のパラメーターを取り、それらのパラメーターを次元として使用して n 次元配列を返す関数を作成することを考えていました。これで、ポインターを使用して 1 次元および 2 次元の配列を簡単に実装できることがわかりました。2 次元配列の場合、スニペットは (標準的な方法) のようになります。

int** x;
int* temp;

x = (int**)malloc(m * sizeof(int*));
temp = (int*)malloc(m*n * sizeof(int));
for (int i = 0; i < m; i++) {
  x[i] = temp + (i * n);
}

配列のサイズは m*n です。しかし問題は、n 次元配列のネストされたループ パラメーターをどのように見つけるかということです。コードを最適化する方法はありますか?

4

2 に答える 2

11

これは、N 次元配列を作成する方法と、その要素にインデックスを付ける方法を示しています。これらは、必要な基本的なメカニズムを提供します。これは学生が学習時に考慮するものですが、実際にはほとんど使用されません。通常、データ構造を整理するためのより良い方法があります。さらに、ほとんどの有用なアルゴリズムには、データをトラバースする方法にパターンがあるため、以下に示すようにゼロからインデックスを再計算するのではなく、インクリメンタルに効率的にインデックスを更新するコードを作成することをお勧めします。

/*  Note:  For demonstration purposes only.  Depending on needs, other types
    might be used for indices and sizes, and the array type might be wrapped
    in an opaque struct rather than exposed as "int *".
*/


//  Create an array with N dimensions with sizes specified in D.
int *CreateArray(size_t N, size_t D[])
{
    //  Calculate size needed.
    size_t s = sizeof(int);
    for (size_t n = 0; n < N; ++n)
        s *= D[n];

    //  Allocate space.
    return malloc(s);
}

/*  Return a pointer to an element in an N-dimensional A array with sizes
    specified in D and indices to the particular element specified in I.
*/
int *Element(int *A, size_t N, size_t D[], size_t I[])
{
    //  Handle degenerate case.
    if (N == 0)
        return A;

    //  Map N-dimensional indices to one dimension.
    int index = I[0];
    for (size_t n = 1; n < N; ++n)
        index = index * D[n] + I[n];

    //  Return address of element.
    return &A[index];
}

使用例:

//  Create a 3*3*7*7*9 array.
size_t Size[5] = { 3, 3, 7, 7, 9 };
int *Array = CreateArray(5, Size);

//  Set element [1][2][3][4][5] to -987.
*Element(Array, 5, Size, (size_t []) { 1, 2, 3, 4, 5 }) = -987;
于 2013-11-09T22:50:42.710 に答える
2

私は多次元配列を使用しないことを好み、代わりに 1D を使用します。

int* pArray = (int*) malloc(m * n * sizeof(int*));

// access pArray[a][b]
int result = pArray[a*m + b];
于 2013-11-09T22:43:04.463 に答える