将2D数组映射到1D数组

时间:2017-04-21 03:58:45

标签: arrays algorithm

为了好玩,我试图在 1D 数组中表示 2D 数组。如何将二维数组映射到一维数组?

例如,假设我们得到一个数组:

char[][] 2dArray = new char[4][4];

在二维空间中,范围(0,0),(2,2)将代表9个元素(在下面表示为O): O, O, O, X O, O, O, X O, O, O, X X, X, X, X

如果我们将二维数组表示为一维数组:

char[] 1dArray = new char[16];

它看起来像这样:

O, O, O, X, O, O, O, X, O, O, O, X, X, X, X, X

我已经知道我可以通过以下公式找到我的1维数组中单个点的索引:(rows * x + y)

即。在给定示例中,2d点(2,3)将映射到1d索引11

给定一对 2D 坐标,如何将矩形截面的点映射到 1D 数组?如果可能的话,我不想使用循环嵌套。

4 个答案:

答案 0 :(得分:2)

假设chars的矩形二维数组如下:

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';

然后将x,y坐标转换为1D索引并返回,您可以使用:

i=x+(xs*y);
x=i%xs;
y=i/xs;

或者这个:

i=y+(ys*x);
x=i%ys;
y=i/ys;

它只是改变了1D数组中项目的顺序。要将整个数组复制到1D,您需要使用2个嵌套循环,或者仅添加DMA或任何其他内存传输的单个循环。像这样:

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";

或:

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";

不需要X ...除非您想在每行/每行的末尾添加空终止字符以简化调试视图或将行或列作为字符串处理。在这种情况下,您可以为行大小添加+1并添加终止字符。

答案 1 :(得分:0)

很容易,首先决定存储顺序(列主要或行主要),然后使用嵌套循环从2D矩阵A填充1D数组B

示例:

ANxM矩阵

for i in 
    for j in M
        B[i*M + j] = A[i][j]

答案 2 :(得分:0)

如果你不想要新的循环,我认为你需要一些语言功能。 这是我在python中的例子。

首先,我们创建一个维度a的列表4 x 4,其中a[i][j](i, j)的元组

a = [[(i, j) for j in range(4)]for i in range(4)]

现在假设我们只想要从(1, 1)(2, 3)的子矩阵。 首先让过滤元素从第1行到第2行

rows = a[1:3]

然后我们得到col 1和col 3之间的元素来获得子矩阵。

submatrix = [row[1:4] for row in rows]

现在我们有子矩阵,将其转换为1d列表,我们可以使用sum

ans = sum(submatrix, [])

最后,如果我们打印ans,我们就会

[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)]

将事物组合在一起,我们有这个功能,其中a是输入矩阵,p1p2是用于定位子矩阵的输入点

def f(a, p1, p2):
    x1, y1 = p1
    x2, y2 = p2

    return sum([row[y1:y2 + 1] for row in a[x1:x2 + 1]], [])

答案 3 :(得分:0)

没有嵌套循环并且没有语言支持(并且还没有提到),但是我怀疑它会更快(具有n行和m列的数组):

for (int i = 0; i < n * m; i++)
    arr1D[i] = arr2D[i / m][i % m];

模数显然给出0,1,2,...,m - 1然后再次从0开始,因为它应该在整数行之后将整数除法的结果增加1。或者逐列阅读(在大多数语言中更糟糕,如上所述,更好地逐行阅读):

for (int i = 0; i < n * m; i++)
    arr1D[i] = arr2D[i % n][i / n];    

然而,这仅适用于矩形矩阵。反例:

int[][] arr2D = new int[2][];
arr2D[0] = new int[1];
arr2D[1] = new int[2];

在这种情况下,最好以标准方式进行,使用此处的列表,因为我不知道结果的长度是多少(如果可能为null则添加空检查) :

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