例如,我想从这样的数组中提取子数组,其中arr
是一个三维数组,"all"
表示该索引位置的所有可能值都是选自:
getSubArray(arr, ["all","all",1])
返回arr的二维切片,arr
的索引为["all", "all", 1]
。
getSubArray(arr,["all",2,2])
应返回arr
的一维数组,其中arr
的索引为["all", 2, 2]
。
答案 0 :(得分:2)
一种相对简单的方法是将此任务作为维度N
的K元组到维度M < N
的K元组的递归映射。由于这与语言无关,因此需要以您的目标语言提供以下工具:
N
- dim数组的实例,找到N
N
- dim数组和k < N
的实例,查找维k
N
- dim数组A
的实例和N
整数I
的向量,在项目中由索引定义的位置获取或设置项目向量。例如,如果向量为I = {2, 3, 4}
,则需要执行从3-D数组A[2, 3, 4]
和向量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;
}
答案 1 :(得分:0)
即使维度的数量是可变的,除非我遗漏了什么,否则这看起来相当简单?
看起来您可以解析第二个参数,找出结果的维度,然后将数据复制到结果中。复制数据并不困难,因为您只能找到arr
子阵列的长度,或者如果语言不支持它,您可以将维度作为参数传入。