多维数组中元素的位置[C]

时间:2022-04-22 21:35:50

I have to write a function that receives an integer X (the value of the linearized position) and an array that contains the dimensions of a multidimensional array and it has to save in a second array the coordinates of the element with position X in the multidimensional reference system. For example:

我必须写一个函数,它接收一个整数X(线性化的位置的值)和一个包含多维数组维数的数组,它必须在第二个数组中保存在多维参考系统中位置X的元素的坐标。例如:

X=2 and array[]={A,B} where the array contains the dimensions(A,B) of a 2D matrix in this example. So the position in 2D reference system is:

X=2和数组[]={A,B},在这个例子中数组包含二维矩阵的维(A,B)。所以二维参考系统的位置是:

Knowing: X=x*B+y ----> x=X/B and y=X%B ----> position[]={x,y};

知道:X = X * B + y - - - - - > X = X / y = X % B - - - - - >位置[]= { X,y };

So it was simple to decipher X into x and y because it was the banal case of a 2D matrix but my program has to deal with N-dimensional matrix (So it has to decipher X into position x,y,......,n) .

所以很容易把X分解成X和y因为这是一个二维矩阵的平凡例子但是我的程序必须处理n维矩阵(所以它必须把X解码成X,y,…,n)。

My idea is to apply the algorithm that I've showed but even I can't find a C code that can deal with a generic N-dimensional matrix (I also tried to write a recursive function without success).

我的想法是应用我已经展示过的算法,但即使是我也找不到一个C代码来处理一个通用的n维矩阵(我也试着在没有成功的情况下写递归函数)。

Can someone find a solution to this problem? (Thank you in advance!!!)

有人能找到解决这个问题的办法吗?(提前谢谢! ! !)

I'm a beginner!!!

我是一个新手! ! !

1 个解决方案

#1


0  

if you have an array DIM2[X,Y] with dimenstions Xn and Yn, you could represent this (as you said) as a one dimenstional array too.

如果你有一个数组DIM2[X,Y]和维数的Xn和Yn,你可以把这个(如你所说的)表示成一个一维数组。

A[x,y] would then be mapped to DIM1[x + y * Xn]

然后将A[x,y]映射到DIM1[x + y * Xn]

DIM1 must have size (Xn * Yn)

DIM1必须有size (Xn * Yn)

3 dimension array B[] with dimensions Xn,Yn,Zn could be mapped the same way:

三维数组B[]与维度Xn,Yn,Zn可以被映射成相同的方式:

B[x,y,z] would map to DIM1 [ x + y * Xn + z * Xn * Yn], DIM1 must be able to hold (Xn * Yn * Zn) items,
B[x,y,z,a] would map to DIM1 [ x + y * Xn + z * Xn * Yn + a * Xn * Yn * Zn]

B(x,y,z)将映射到DIM1[x + y * Xn + z * Xn * Yn),DIM1必须能够容纳(Xn * Yn *锌)项目,B(x,y,z,)会映射到DIM1[x + y * Xn + z * Xn * Yn + * Xn * Yn *锌)

and so on

等等

for a generic N dimensional array, a recursion would be best, where an array with 100 dimensions is array of 99-dimensional arrays. If all dimenstions have the same size, that would be relative simple (writing it, i also mentioned that the recursion can be easily unrolled into a simple for-loop, find it below)

对于一般的N维数组,递归是最好的,其中包含100维的数组是99维数组的数组。如果所有的维度都有相同的大小,那将是相对简单的(编写它,我也提到了递归可以很容易地展开成一个简单的for循环,在下面找到它)

    #include <stdio.h>
    #include <math.h>
    #include <malloc.h>

    #define max_depth  5    /* 5 dimensions        */
    #define size      10    /* array[10] of array  */

    // recursive part, do not use this one
    int _getValue( int *base, int offset, int current, int *coords) {
        if (--current)
           return _getValue (base + *coords*offset, offset/size, current, coords+1);

        return base[*coords];
    }
    // recursive part, do not use this one
    void _setValue( int *base, int offset, int current, int *coords, int newVal) {
        if (--current)
           _setValue (base + *coords*offset, offset/size, current, coords+1, newVal);
        base[*coords]=newVal;
    }

    // getValue: read item
    int getValue( int *base, int *coords) {
        int offset=pow( size, max_depth-1);   /* amount of ints to skip for first dimension */
        return (_getValue (base, offset, max_depth, coords));
    }
    // setValue: set an item
    void setValue( int *base, int *coords, int newVal) {
        int offset=pow( size, max_depth-1);
        _setValue (base, offset, max_depth, coords, newVal);
    }

    int main() {
        int items_needed = pow( size, max_depth);

        printf ("allocating room for %i items\n", items_needed);
        int *dataholder = (int *) malloc(items_needed*sizeof(int));
        if (!dataholder) {
            fprintf (stderr,"out of memory\n");
            return 1;
        }
        int coords1[5] = { 3,1,2,1,1 };    // access member [3,1,2,1,1]
        setValue(dataholder, coords1, 4711);
        int coords2[5] = { 3,1,0,4,2 };
        int x = getValue(dataholder, coords2);

        int coords3[5] = { 9,7,5,3,9 };
        /* or: access without recursion: */
        int i, posX = 0;                           // position of the wanted integer
        int skip = pow( size, max_depth-1);        // amount of integers to be skipped for "pick"ing array
        for (i=0;i<max_depth; i++) {
            posX += coords3[i] * skip;             // use array according to current coordinate
            skip /= size;                          // calculate next dimension's size
        }
        x = dataholder[posX];

        return x;
    }

#1


0  

if you have an array DIM2[X,Y] with dimenstions Xn and Yn, you could represent this (as you said) as a one dimenstional array too.

如果你有一个数组DIM2[X,Y]和维数的Xn和Yn,你可以把这个(如你所说的)表示成一个一维数组。

A[x,y] would then be mapped to DIM1[x + y * Xn]

然后将A[x,y]映射到DIM1[x + y * Xn]

DIM1 must have size (Xn * Yn)

DIM1必须有size (Xn * Yn)

3 dimension array B[] with dimensions Xn,Yn,Zn could be mapped the same way:

三维数组B[]与维度Xn,Yn,Zn可以被映射成相同的方式:

B[x,y,z] would map to DIM1 [ x + y * Xn + z * Xn * Yn], DIM1 must be able to hold (Xn * Yn * Zn) items,
B[x,y,z,a] would map to DIM1 [ x + y * Xn + z * Xn * Yn + a * Xn * Yn * Zn]

B(x,y,z)将映射到DIM1[x + y * Xn + z * Xn * Yn),DIM1必须能够容纳(Xn * Yn *锌)项目,B(x,y,z,)会映射到DIM1[x + y * Xn + z * Xn * Yn + * Xn * Yn *锌)

and so on

等等

for a generic N dimensional array, a recursion would be best, where an array with 100 dimensions is array of 99-dimensional arrays. If all dimenstions have the same size, that would be relative simple (writing it, i also mentioned that the recursion can be easily unrolled into a simple for-loop, find it below)

对于一般的N维数组,递归是最好的,其中包含100维的数组是99维数组的数组。如果所有的维度都有相同的大小,那将是相对简单的(编写它,我也提到了递归可以很容易地展开成一个简单的for循环,在下面找到它)

    #include <stdio.h>
    #include <math.h>
    #include <malloc.h>

    #define max_depth  5    /* 5 dimensions        */
    #define size      10    /* array[10] of array  */

    // recursive part, do not use this one
    int _getValue( int *base, int offset, int current, int *coords) {
        if (--current)
           return _getValue (base + *coords*offset, offset/size, current, coords+1);

        return base[*coords];
    }
    // recursive part, do not use this one
    void _setValue( int *base, int offset, int current, int *coords, int newVal) {
        if (--current)
           _setValue (base + *coords*offset, offset/size, current, coords+1, newVal);
        base[*coords]=newVal;
    }

    // getValue: read item
    int getValue( int *base, int *coords) {
        int offset=pow( size, max_depth-1);   /* amount of ints to skip for first dimension */
        return (_getValue (base, offset, max_depth, coords));
    }
    // setValue: set an item
    void setValue( int *base, int *coords, int newVal) {
        int offset=pow( size, max_depth-1);
        _setValue (base, offset, max_depth, coords, newVal);
    }

    int main() {
        int items_needed = pow( size, max_depth);

        printf ("allocating room for %i items\n", items_needed);
        int *dataholder = (int *) malloc(items_needed*sizeof(int));
        if (!dataholder) {
            fprintf (stderr,"out of memory\n");
            return 1;
        }
        int coords1[5] = { 3,1,2,1,1 };    // access member [3,1,2,1,1]
        setValue(dataholder, coords1, 4711);
        int coords2[5] = { 3,1,0,4,2 };
        int x = getValue(dataholder, coords2);

        int coords3[5] = { 9,7,5,3,9 };
        /* or: access without recursion: */
        int i, posX = 0;                           // position of the wanted integer
        int skip = pow( size, max_depth-1);        // amount of integers to be skipped for "pick"ing array
        for (i=0;i<max_depth; i++) {
            posX += coords3[i] * skip;             // use array according to current coordinate
            skip /= size;                          // calculate next dimension's size
        }
        x = dataholder[posX];

        return x;
    }