0

私はオープン ソースの科学ライブラリ (C で記述) に取り組んでおり、サポートしたい操作の 1 つは、「プロデューサー」から多次元配列の任意のスライスを「コンシューマー」にコピーさせることです。たとえば、4x5 の 2D 配列があるとします (フォーマットについては申し訳ありません)。

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 開始)

count[2] = {3, 2} (x カウント、y カウント)

これは、0 の位置から始まる x 次元の場合は 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 コードであり、正直なところ、問題を解決するためにアルゴリズムを考えてコードに変換することはできません。私は生物学のバックグラウンドを持っているので、コーディングのアルゴリズム的な考え方についてはあまり経験がありません。

これを解決する方法について何か提案はありますか? 多くの助けをいただければ幸いです!

4

2 に答える 2

0

各次元の開始のオフセットを計算する必要があります。

与えられた array[5][6][7][8] ;// インデックス a、b、c、d などと次元 dim(a)=5、dim(b) =6、dim(c)=7 、dim(d) =8

インデックス a の場合、position(0): pos(a[0]) = 0 これは実際には 0*6*7*8 です

インデックス a の場合、position(a[1]) は 0 {pos(a[0]} + 1 (インデックス a の現在の値) *6*7*8

一般に、インデックス a の場合、position(n) = pos(a[0]) + n * dim(b)*dim(c)*dim(d)

このような直線的な配置では、問題はタマネギになり、外側の寸法をはがして内側の寸法内の位置を見つけます

インデックス b の場合、位置 (または値) 0 はインデックス a の値に依存します

したがって、インデックス b については、pos(a[2]) に対する相対的な位置を pos(a[2]b[0]) = pos(a[2]) + position(b[0]) として書き込みます。

pos(a[0]) と同様に、pos(b[0]) も 0 です。<0*dim(c)*dim(d)> ですが、現在は有効な値 0<=n<=dim(a) の pos(a[n]) に相対的です

だから pos(a[2]b[0]) = 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(a[i]b[j]c[k]d[l]) に進み、要素を選択する必要があります。 d[l] と d[l+1]

次に pos(a[i],b[j+1],c[k],d[l]) に戻り、再び 2 つの項目 d[l] と d[l+1] を選択します。

明らかに、このソリューションは再帰関数によって提供されるのが最適です。

私はプロジェクトの締め切り (残り 2.5 週間) に縛られていますが、その後にコードを設定しようとすることができます... 他の誰もあなたの挑戦を受け入れる勇気がない場合.

于 2013-07-27T10:59:27.123 に答える
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.
      }
 }
于 2013-07-26T20:50:18.660 に答える