2017-04-21 617 views
0

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

例如,假设我们给出阵列:

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

在2维空间中,该范围(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 

我已经知道我能找到一个单点的指数,我通过公式一维数组:(rows * x + y)

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

给定一对2D坐标,我怎样才能点的矩形截面映射到1D数组?如果可能,我宁愿不使用循环嵌套。

+0

你问一个没有嵌套循环的解决方案,并接受一个使用嵌套循环......做得很好。 – maraca

回答

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]= 
    { 
    "", 
    "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,您需要使用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[]="abcdefghijklmn"; 

或:

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作为行大小并添加终止字符。

+0

当使用嵌套循环和性能问题时,对于大多数语言,最好对列使用内部循环(就像在最后一个代码片段中那样),因为那样你自然地扫描数组,否则你在内存中进行跳转。 – maraca

+0

@maraca转换时间并不像最终的一维数组访问模式/用法那样重要,因为转换通常只进行一次,但访问是圆顶多次......但是顺序访问通常更快 – Spektre

+0

感谢您的支持清楚的解释! – chemoroti

0

这是很容易,首先决定用于存储顺序(列主要或行主要),然后用一个嵌套循环你从2D矩阵A 1D阵列B填写:

实施例:

ANxM矩阵

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

我想你会需要一些语言功能,如果你不想要neseted循环。 这是我在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行的过滤器元件行到第2

rows = a[1:3]

然后我们得到第1栏和第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]], []) 
0

很可能没有嵌套循环,没有语言支持的输入点(并没有提到)但我怀疑它会更快(阵列具有n行和m列):

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

模数明显赋予0,1,2,...,M - 1,然后从0开始再次的,因为它应该和整数除的结果在一行满后增加一个。或通过列读取列(在大多数语言差,更好地行逐行读取如上):

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