2013-07-26 21 views
0

我正在開發一個開源的科學庫(用C編寫),我們希望支持的操作之一是讓「消費者」複製出多維數組的任意切片來自「製片人」。例如,讓我們假設有一個4x5 2D陣列(I爲格式化道歉):選擇多維數組的切片的算法

10,20,30,40

50,60,70,80

90,100,110 ,120

130,140,150,160

170,180,190,200

這些暴露雖然作爲大小20的線性陣列:10,20,30,40,50, 60,...,200

用戶代碼主要通過在偏移量,並且計數(基本上座標),它要選擇:

開始[2] = {0,2}(X起始,Y起始)

計數[ 2] = {3,2}(x count,y count)

這意味着對於x維度,從0開始,給我3(x座標範圍是[0:2]),對於y維度,從位置2開始,給我2(y座標範圍,然後是[3,4])。

這應導致

130,140,150,170,180,190

複製到用戶緩存(這將是長度爲6的)。

所以我們知道:我們知道數組的維數大小(4x5),維數(2)以及用戶想要的「座標」。

數組的尺寸可以是任意數量的維數1,2,3 ... 6? 100?因爲它在科學應用程序中非常常見,因此您的陣列具有非常大的尺寸。

這是C代碼,我真的不能想到一個算法,並將其轉化爲代碼來解決問題。我來自生物學背景,所以我對編碼的算法思維方面不太熟悉。

有沒有人有任何建議如何解決這個問題?很多幫助表示讚賞!

+0

看到我的答案[這裏](http://stackoverflow.com/questions/30409991/use-a-dope-vector-to-access-arbitrary-slices-of-a-multidimensional-array/30409992#30409992) 。 –

回答

0

爲了獲得線性數組的起點,您必須使用start [0] * numColumns + start [1]。你必須有一個循環,就像

即使使用線性數組,你也可以使用多維語法訪問一個元素,因爲c在內部將多維數組存儲爲線性數組。

for(int i = start[0], countx = 0, count < xcount; countx++, i++) { 
     for(int j = start[1], county = 0; county < ycount; county++, j++) { 
      // copy array[i][j] into another array. 
     } 
} 
+0

謝謝你的回覆。這將適用於2維數組。但是,我無法擴展這個任意維數組的基本概念。你有什麼想法,我怎麼可以將它擴展到n維?謝謝! – Dunn

+0

我想清楚一點,我不知道編譯時的數組維數;要交換的數組在運行時確定。 – Dunn

0

您必須計算每個維度的開始偏移量。

給定數組[5] [6] [7] [8]; //索引a,b,c,d等對於索引a,位置(0):pos(a [0])= 0,dim(a)= 5,dim(b)= 6,dim(c)= 7,dim(d)= 8

= (a [0]} + 1(索引a的當前值)* 6 * 7 * 8

並且通常爲索引,位置(N)= POS(A [0])+ N *暗淡(b)*暗淡(C)*暗淡(d)

現在以線性佈置比如這樣,你的問題就變成了洋蔥,剝開外面的兩個小孔,找到內部尺寸的位置

索引B,位置(或值)0是依賴於指數的值的

所以對於索引A我們寫出相對於POS的位置([2])爲 POS(A [2] B [ 0])= pos(a [2])+ position(b [0])

like pos(a [0]),pos(b [0])也是0; < = dim(a)

so pos(a [2] 0 * dim(c)* dim(d)>,但其相對於pos(a [n])現在相對於任何有效值0 < = n < = dim (b [1])= pos(a [2])+ 0

pos(a [2] b [1])是pos(a [2])+ pos(b [1]) 其中posb [1]是0 + 1 * dim(c)* dim(d)

因此對於任何給定的座標pos(a [i] b [j] c [k],d [l]) 您的陳述位置是pos(a [i])+ pos(b [j],+ pos(c [k])+ pos(d [l])

要選擇任意數量的元素,來自最後一維d的集合。

如果你想要a的2個單位,b的3個單位,c的1個單位和d的2個單位,你需要前進到pos )並選擇元素d [1]和d [1 + 1]然後回到pos(a [i],b [j + 1],c [k],d [1])並再次選擇兩個項目d [l]和d [l + 1]。

顯然,這個解決方案最好由遞歸函數提供服務。

我與一個項目截止日期(2.5周左右)捆綁在一起,但我可以嘗試設置代碼之後...如果沒有人敢接受你的挑戰。