【问题标题】:Algorithm to select slices of a multidimensional array选择多维数组切片的算法
【发布时间】:2013-07-27 06:12:45
【问题描述】:

我正在开发一个开源科学库(用 C 语言编写),我们想要支持的操作之一是让“消费者”从“生产者”复制多维数组的任意切片。例如,假设我们有一个 4x5 二维数组(我为格式化道歉):

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 计数)

这意味着对于 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代码,老实说我想不出一个算法,把它变成代码来解决问题。我来自生物学背景,所以我对编码的算法思维方面没有太多经验。

有人对如何解决这个问题有任何建议吗?非常感谢您的帮助!

【问题讨论】:

  • 看我的回答here

标签: arrays multidimensional-array slice


【解决方案1】:

为了在线性数组中获得起点,您必须使用 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.
      }
 }

【讨论】:

  • 感谢您的回复。这将适用于二维数组。但是,我在为任意维度数组扩展这个基本概念时遇到了麻烦。您有什么想法可以将其扩展到 n 维吗?谢谢!
  • 我想清楚,我不知道编译时的数组维度;要交换的数组在运行时确定。
【解决方案2】:

您必须计算每个维度开始的偏移量。

Given array[5][6][7][8] ;//索引a,b,c,d等,维度dim(a)=5,dim(b)=6,dim(c )=7, 暗淡(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]) 的位置写为 位置(a[2]b[0]) = 位置(a[2]) + 位置(b[0])

和pos(a[0])一样,pos(b[0])也是0; ,但它现在相对于任何有效值 0 的 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)

so 对于任何给定的坐标 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]) 并再次选择两个项目 d[l] 和 d[l+1]。

显然,这个解决方案最好由递归函数提供。

我的项目截止日期(还剩 2.5 周)很紧张,但我可以尝试在那之后设置代码......如果没有其他人敢于接受你的挑战。

【讨论】:

    猜你喜欢
    • 2020-05-03
    • 2021-11-23
    • 2014-08-25
    • 2013-02-01
    • 1970-01-01
    • 2019-05-09
    • 2018-03-29
    • 1970-01-01
    相关资源
    最近更新 更多