2017-04-21 621 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]);