繁体   English   中英

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

[英]Map 2D array into 1D array

为了好玩,我尝试用1D数组表示2D数组。 如何将2维数组映射到1维数组?

例如,假设给定一个数组:

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

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

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

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

它看起来像这样:

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

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

也就是说,在给定示例中,第2d点(2,3)将映射到第1d索引11

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

假设像这样的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坐标转换为一维索引并返回,您可以使用:

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

或这个:

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

没关系,它只是更改一维数组中项目的顺序。 要将整个阵列复制到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并添加终止符。

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

例:

A是一个NxM矩阵

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

我认为,如果您不希望使用嵌套循环,则需要一些语言功能。 这是我在python中的示例。

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

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

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

rows = a[1:3]

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

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

现在我们有了子矩阵,将其转换为一维列表,我们可以使用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]], [])

有可能没有嵌套循环,也没有语言支持(尚未提到),但是我怀疑它会更快(具有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]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM