Warm tip: This article is reproduced from stackoverflow.com, please click
algorithm arrays c++ multidimensional-array templates

How to convert an M-dimensional array to an N-dimensional array?

发布于 2020-03-28 23:14:06

Inspired by arr2D[i][j] and arr1D[i * k + j], I would like to know an algorithm that can change the dimensions of any array.

Let me try to formalize it:

Input:

  1. An M-dimensional container A

  2. The dimensions D of the container (size)

  3. Target dimension N

Output:

If N > 0 then return an N-dimensional container B with the same contents as A in order otherwise return an error code.

Note:

You may choose any optimal size for the N-dimensional container.

I would understand a C++ or C code better than an algorithm or a code in some other language. But you may help my curiosity in any language as long as it is comprehensible in English :P

Edit:

I don't need any fully working code. I'm just asking for ways to approach this problem. Thanks in advance for any good ideas.

Questioner
Ardent Coder
Viewed
97
Spektre 2020-01-31 23:40

So you just want to reformat your matrices while no data is changed. As I hinted in my comment the simplest is to use 1D array mid step for converting from M to N dimensions.

The other answers here are on the same track but are lacking the whole math ... they have just examples up to some small dimension without universal equation so here it is:

To convert between A[A0][A1]...[A(M-1)] and X[A0*A1*...*A(M-1)] where A0,A1,...A(M-1) are the dimension sizes of your container (resolution) simply do this:

// M-D -> 1D
x = a0
   +a1*A0
   +a2*A0*A1
   ...
   +a(M-1)*A0*A1*...*A(M-2);

// 1D -> M-D   
q=x;
a0 = q%A0; q/=A0;
a1 = q%A1; q/=A1;
a2 = q%A2; q/=A2;
...
a(M-1) = q%A(M-1); q/=A(M-1);

where a0,a1,...a(M-1) and x are the indexes in the arrays.

You actually do not need to convert the M-D array into 1D and then back to N-D its enough to just convert the indexes so:

for (a0=0;a0<A0;a0++)
 for (a1=0;a1<A1;a1++)
  ...
   for (a(M-1)=0;a(M-1)<A(M-1);a(M-1)++)
      {
      // M-D -> 1D
      x = a0
         +a1*A0
         +a2*A0*A1
         ...
         +a(M-1)*A0*A1*...*A(M-2);
      // 1D -> N-D   
      q=x;
      b0 = q%B0; q/=B0;
      b1 = q%B1; q/=B1;
      b2 = q%B2; q/=B2;
      ...
      b(N-1) = q%B(N-1); q/=B(N-1);
      // copy A -> B
      B[b0][b1]...[b(N-1)] = A[A0][A1]...[A(M-1)];
      }

Do not forget that the sizes must be:

A0*A1*...*A(M-1) <= B0*B1*...*B(N-1)

otherwise you will access array out of its bounds as the data in A will not fit into B.

In case you got dynamic dimensionality you can use: