For fun, I am trying to represent a 2D array in 1D array. How can I map a 2-dimensional array to 1 dimensional array?
For example, suppose we are given an array:
char[][] 2dArray = new char[4][4];
In 2-dimensional space, the range (0,0),(2,2)
would represent 9 elements (represented as O below): O, O, O, XO, O, O, XO, O, O, XX, X, X, X
If we represent the two-dimensional array as a 1-dimensional array:
char[] 1dArray = new char[16];
it would look like this:
O, O, O, X, O, O, O, X, O, O, O, X, X, X, X, X
I already know that I can find the index of a single point in my 1-dimensional array via the formula: (rows * x + y)
.
ie the 2d point (2,3)
would map to the 1d index 11
in the given example.
Given a pair of 2D coordinates, How can I map a rectangular section of points to a 1D array? I prefer not to use loop nesting, if possible.
Let assume rectangular 2D array of chars
like these:
const int xs=6; // columns
const int ys=4; // rows
char dat2D_xy[xs][ys]=
{
"06ci",
"17dj",
"28ek",
"39fl",
"4agm",
"5bhn",
};
char dat2D_yx[ys][xs]=
{
"012345",
"6789ab",
"cdefgh",
"ijklmn",
};
dat2D_xy[5][3] == dat2D_yx[3][5] == 'n';
Then to convert x,y
coordinates to 1D index and back you can use:
i=x+(xs*y);
x=i%xs;
y=i/xs;
Or this:
i=y+(ys*x);
x=i%ys;
y=i/ys;
Does not matter which it just changes the order of items in the 1D array. To copy whole array to 1D you need to use 2 nested loops or just single one with addition to DMA or any other memory transfer. Something like this:
int i,x,y;
char dat1D[xs*ys];
for (i=0,y=0;y<ys;y++)
for (x=0;x<xs;x++,i++)
dat1D[i]=dat2D_xy[x][y];
//dat1D[i]=dat2D_yx[y][x];
//dat1D[]="0123456789abcdefghijklmn";
or:
int i,x,y;
for (i=0,x=0;x<xs;x++)
for (y=0;y<ys;y++,i++)
dat1D[i]=dat2D_xy[x][y];
//dat1D[i]=dat2D_yx[y][x];
//dat1D[]="06ci17dj28ek39fl4agm5bhn";
There are no X
needed ... unless you want to add also the null termination characters at the end of each row/line to ease up debug view or process rows or columns as strings. In such case you add +1
for line size and add your termination character.
It is easy, first decide for a storage order (column major or row major), then with a nested loop you fill from 2D matrix A
the 1D array B
:
Example:
A
is a NxM
matrix
for i in
for j in M
B[i*M + j] = A[i][j]
I think you will need some language features if you don't want neseted loop. This is my example in python.
First lets create a list a
of dimension 4 x 4
where a[i][j]
is a tuple of (i, j)
a = [[(i, j) for j in range(4)]for i in range(4)]
Now suppose we only want the submatrix from (1, 1)
to (2, 3)
. First lets filter elements from row 1 to row 2
rows = a[1:3]
Then we get the elements between col 1 and col 3 to get the submatrix.
submatrix = [row[1:4] for row in rows]
Now we have the submatrix, to convert it to 1d list, we can use sum
ans = sum(submatrix, [])
Finally if we print ans
, we will have
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)]
Combining things together, we have this function, where a
is the input matrix, p1
and p2
are input points for locating the submatrix
def f(a, p1, p2):
x1, y1 = p1
x2, y2 = p2
return sum([row[y1:y2 + 1] for row in a[x1:x2 + 1]], [])
It is possible without nested loop and no language support (and wasn't mentioned yet), but I doubt it will be faster (array with n rows and m columns):
for (int i = 0; i < n * m; i++)
arr1D[i] = arr2D[i / m][i % m];
The modulo obviously gives 0, 1, 2, ..., m - 1 and then starts at 0 again, as it should and the result of the integer division is increased by one after a row is full. Or to read column by column (worse in most languages, better read row by row as above):
for (int i = 0; i < n * m; i++)
arr1D[i] = arr2D[i % n][i / n];
However this works only with rectangular matrices. Counter example:
int[][] arr2D = new int[2][];
arr2D[0] = new int[1];
arr2D[1] = new int[2];
In this case it would be best to do it in the standard way, using a list here because I don't know what the length of the result is going to be (add null checks if null is a possibility):
List<Integer> list = new ArrayList<>();
for (int i = 0; i < arr2D.lengh; i++)
for (int j = 0; j < arr2D[i].length; j++)
list.add(arr2D[i][j]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.