2

たとえば、次のような配列からサブ配列を抽出したいと思います。ここarrで、 は 3 次元配列であり、"all"そのインデックス位置で可能なすべての値が選択されることを意味します。

getSubArray(arr, ["all","all",1])arrからのインデックスを使用して、arr の 2 次元スライスを返します["all", "all", 1]

getSubArray(arr,["all",2,2])からの 1 次元配列を返す必要があります。arrインデックスはarrです["all", 2, 2]

4

2 に答える 2

2

One relatively simple way is to approach this task as a recursive mapping of K-tuples of dimension N to K-tuples of dimension M < N. Since this is language-agnostic, the following facilities need to be available in your target language:

  1. Given an instance of an N-dim array, find N
  2. Given an instance of an N-dim array and a k < N, find the number of items in dimension k
  3. Given an instance of an N-dim array A and a vector of N integers I, get or set the item at a position defined by indexes in the vector. For example, if the vector is I = {2, 3, 4}, there needs to be an operation for obtaining A[2, 3, 4] from the 3-D array A and a vector I.
  4. Given a vector D of size M defining dimensions, there needs to be an operation for constructing an array of M dimensions, each dimension taking the size of the corresponding item in the vector. For example, if the vector D = {3, 4}, there needs to be an operation that creates a 2-D array with dimensions 3 and 4.

Preprocess the request by constructing vectors F and D as follows:

  • For each "all" item at position i of the request, F[i] = -1 and D[i] = size(dimension[i])
  • For each numeric item k at position i of the request, F[i] = k and D[i] = 0.
  • Create an array for the result by taking all non-fixed indexes and passing them to the array constructor (prerequisite number four above).

Now your recursive procedure should look relatively straightforward:

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
    }
}

Your getSubarray would look like this:

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;
}
于 2013-07-08T21:47:08.037 に答える
0

次元の数が可変であっても、何かが欠けていない限り、これはかなり簡単に思えますか?

2 番目の引数を解析し、結果の次元を調べてから、データを結果にコピーできるようです。サブ配列の長さを見つけることができるarr か、言語がそれをサポートしていない場合は、次元をパラメーターとして渡すことができるため、データをコピーするのは難しくありません。

于 2013-07-08T21:30:39.747 に答える