例如,我想从这样的数组中提取子数组,其中arr
是一个 3 维数组,"all"
这意味着选择了该索引位置的所有可能值:
getSubArray(arr, ["all","all",1])
arr
返回 arr的二维切片,索引来自["all", "all", 1]
。
getSubArray(arr,["all",2,2])
应该从 中返回一个一维数组arr
,其中索引arr
为["all", 2, 2]
。
例如,我想从这样的数组中提取子数组,其中arr
是一个 3 维数组,"all"
这意味着选择了该索引位置的所有可能值:
getSubArray(arr, ["all","all",1])
arr
返回 arr的二维切片,索引来自["all", "all", 1]
。
getSubArray(arr,["all",2,2])
应该从 中返回一个一维数组arr
,其中索引arr
为["all", 2, 2]
。
一种相对简单的方法是将此任务视为维度的 K 元组到维度N
的 K元组的递归映射M < N
。由于这与语言无关,因此需要以您的目标语言提供以下工具:
N
-dim 数组的实例,找到N
N
-dim 数组和 a的实例k < N
,找出维度中的项目数k
N
-dim 数组的实例A
和一个N
整数向量I
,在向量中的索引定义的位置获取或设置项目。例如,如果向量是I = {2, 3, 4}
,则需要A[2, 3, 4]
从 3-D 数组A
和向量中获取一个操作I
。D
给定一个大小定义维度的向量M
,需要一个构造维度数组的操作M
,每个维度取向量中对应项的大小。例如,如果是向量D = {3, 4}
,则需要有一个操作来创建一个维度为 3 和 4 的二维数组。通过构造向量对请求进行预处理F
,D
如下所示:
"all"
位置的每个项目,以及i
F[i] = -1
D[i] = size(dimension[i])
k
位置的每个数字项,并且.i
F[i] = k
D[i] = 0
现在您的递归过程应该看起来相对简单:
void RecursiveCopy(Vector F, Vector D, Array S, Vector SI, int sp, Array T, Vector TI, int tp) {
if (pos != TS.size) {
if (F[sp] != -1) {
// This is an "all" dimension
for (int i = 0 ; i != D[sp] ; i++) {
SI[sp] = i;
TI[tp] = i;
RecursiveCopy(F, D, S, SI, sp+1, T, TI, tp+1);
}
} else {
// This is a fixed dimension
SI[sp] = F[sp];
RecursiveCopy(F, D, S, SI, sp+1, T, TI, tp);
}
} else {
// Read from the source at indexes defined by vector SI
var value = S.get(SI);
// Write to the destination at indexes defined by vector TI
T.setValue(TI, value); // Prerequisite 3
}
}
你getSubarray
看起来像这样:
Array getSubarray(Array S, Vector<string> request) {
Vector F = Vector[S.Size]; // The number of dimensions in A; prerequisite 1
Vector D = Vector[S.Size]; // The number of dimensions in A
Assert(request.Size == S.Size); // Request must have N items
int k = 0;
Vector resDim;
for (int i = 0 ; i != req.Size ; i++) {
if (req[i] == "all") {
k++;
F[i] = -1;
D[i] = A.dimensionOf(i); // Prerequisite 2
resDim.Add(D[i]);
} else {
F[i] = ParseInteger(req[i]);
D[i] = -1;
}
}
Array T = Array(resDim); // Prerequisite #4
Vector SI = Vector[S.Size];
Vector TI = Vector[k];
RecursiveCopy(F, D, S, SI, 0, T, TI, 0);
return T;
}
即使维数是可变的,除非我遗漏了什么,否则这似乎相当简单?
似乎您可以只解析第二个参数,找出结果的维度应该是什么,然后将数据复制到结果中。复制数据并不难,因为您可以找到子数组的长度,arr
或者如果语言不支持它,您可以将维度作为参数传入。